Skip to content

feat(libSceAgcDriver): render color views of several 3D slices as layered attachments - #4573

Closed
ee6aba54 wants to merge 2 commits into
boykopovar:mainfrom
ee6aba54:feat/agc-layered-3d-color-slices
Closed

ee6aba54 wants to merge 2 commits into
boykopovar:mainfrom
ee6aba54:feat/agc-layered-3d-color-slices

Conversation

@ee6aba54

Copy link
Copy Markdown
Contributor

What

CB_COLOR_VIEW can select a range of slices (SLICE_START to SLICE_MAX); a draw into a 3D color target then addresses the slice per primitive through the render target index export. The decoder rejected every view whose last slice differs from its first ("color views of several array slices are unsupported"), and the index export was accepted but never routed.

Two commits:

  • A 3D target's view carries its slice count (clamped to the surface depth), the resident image's attachment view becomes a 2D array over those slices, and the framebuffer takes the layer count, which every color target of the draw must share. A depth target alongside a layered draw is still refused, and 2D array targets keep the single-slice rule.
  • For such a draw, PA_CL_VS_OUT_CNTL reaches the vertex stage info (and the draw hash, the recompile cache key and the request serialization, now version 18), so the render target index export becomes a gl_Layer output: per vertex, or per primitive in a mesh shader (the emitter already produced that output; the validation refused it). SPIR-V targets below 1.5 take the vertex built-in from SPV_EXT_shader_viewport_index_layer; the device enables VK_EXT_shader_viewport_index_layer, the validation accepts the vertex built-in with that capability or ShaderLayer and the mesh built-in, and dynamic rendering begins with the framebuffer's layer count instead of 1. Single-slice views keep ignoring the export, which lands on their slice as the hardware clamp would; the viewport index export stays ignored and keeps its one-time log line.

Tested

  • Ubuntu 24.04, Linux 7.0, GCC 13.3, Release, based on 33ae282e4. ctest of a tree combining this branch with fix(libSceAgcDriver): accept DCC on 3D color targets #4499 and feat(libSceAgcDriver): storage image access to depth surfaces #4500: 954 tests pass; video_out_flip_* and agc_driver_stencil_ref_export are skipped on this machine.
  • New agc_vertex_layer_export (recompiler only) checks the SPIR-V 1.3 module takes gl_Layer from the extension without raising its version, the 1.5 module from ShaderLayer, and a misc vector export without the index declares no layer output. New agc_driver_layer_export_slices (RTX 5080) draws into slices 0-3 of a 128x128x4 R32 volume with a vertex shader exporting slice 2 and reads every slice back: only slice 2 changes, also after the volume is written back to guest memory and uploaded again. agc_driver_graphics covers the decode (slice range, clamping, inverted range) and the validation (the vertex Layer built-in needs the device flag). agc_shader_memory pins the new serialization version.
  • PPSA15304 (engine: Unreal Engine 5): the draw into a 48-slice 48x48x48 3D target that stopped the title is a mesh shader draw exporting the slice per primitive; it now runs with the export routed. Together with fix(libSceAgcDriver): accept DCC on 3D color targets #4499, feat(libSceAgcDriver): storage image access to depth surfaces #4500 and a fix for the compute dispatch look-ahead submitted separately, the title reaches its main menu. The mesh built-in is covered only by this title run; no test builds a mesh module with a per-primitive Layer output.
  • Windows not built or tested.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

🤖 Generated with Claude Code

…ered attachments

CB_COLOR_VIEW may select a range of slices; draws into a 3D color target
then address the slice per primitive. The decoder rejected any view whose
last slice differs from its first.

A 3D target's view now carries the slice count, clamped to the surface
depth, and the resident image's attachment view becomes a 2D array over
those slices. The framebuffer takes the layer count, which every color
target of the draw must share; a depth target alongside is still refused.
Array targets keep the single-slice rule.

PPSA15304 renders into a 48-slice 3D target with one draw.
For a draw into a color view of several slices, PA_CL_VS_OUT_CNTL reaches
the vertex stage info (and the draw hash, the recompile cache key and the
request serialization), so the render target index export becomes a
gl_Layer output: per vertex, or per primitive in a mesh shader. SPIR-V
targets below 1.5 take the vertex built-in from
SPV_EXT_shader_viewport_index_layer; the device enables
VK_EXT_shader_viewport_index_layer, the validation accepts both built-ins,
and dynamic rendering begins with the framebuffer's layer count.
Single-slice views keep ignoring the export, which lands on their slice
as the hardware clamp would; the viewport index export stays ignored.
@github-actions

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
#1077 core/libs/prx/libSceAgcDriver/tests/VertexLayerExport.cpp
#1313 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp L147
#3633 core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp L996, L1009-1010
#3763 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp L147
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp L267
core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp L18, L50, L70, L126
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp L57
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp L163, L536
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp L740, L1968, L2156, L2532
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp L72, L84, L567, L582, L592, L605, L632
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp L48, L130, L136-138, L145, L245, L566, L587
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp L100-102, L694-701, L972, L996, L1008-1014
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L1329, L1335, L1342, L1345, L1348
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp L1319, L3325-3329
core/libs/prx/libSceAgcDriver/tests/VertexLayerExport.cpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp L404, L407, L423, L568
core/shader/recompiler/SpirvBackend/src/SpirvMemory/SpirvModuleSetup.cpp L109-111
core/libs/prx/libSceAgcDriver/tests/VertexLayerExport.cpp
#4451 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp L1640, L1645

@ee6aba54

Copy link
Copy Markdown
Contributor Author

Closing as a duplicate of #1077 (layered draws into 3D color targets, the render target index export routed to gl_Layer, VK_EXT_shader_viewport_index_layer) and #3763 (the dynamic rendering layer count). I missed both when I checked for overlapping pull requests.

For those pull requests, in case it helps: PPSA15304 (engine: Unreal Engine 5) renders into a 48-slice 48x48x48 3D target with a mesh shader that exports the slice per primitive, so the per-primitive Layer output of mesh shaders matters there as well as the vertex one. With an equivalent change, #4500 and #4586, the title reaches its main menu.

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