Skip to content

vk: blend constants as dynamic command-buffer state (MARVEL Cosmic Invasion) - #2667

Open
bensaadmucret wants to merge 2 commits into
seedds:mainfrom
bensaadmucret:pr-vk-blend-constants
Open

bensaadmucret wants to merge 2 commits into
seedds:mainfrom
bensaadmucret:pr-vk-blend-constants

Conversation

@bensaadmucret

Copy link
Copy Markdown

What

vkCmdSetBlendConstants recorded into the command buffer (C_BLEND) and replayed into the Metal encoder's blend colour. VK_DYNAMIC_STATE_BLEND_CONSTANTS on a pipeline marks it to take the command buffer's value; other pipelines keep their static blendConstants field, as the Vulkan model wants.

Why

MARVEL Cosmic Invasion (FNA/SDL_GPU, title 010059D020C26000) draws its player character sprites through a blend factor that reads the constant colour; the run log showed [RED] dynamic state 4 not implemented and the sprites blended to nothing — a shadow and the enemies (straight alpha blending) drew fine. After the fix the sprites draw and the log has no [RED] left.

Depends on

Checked

  • make -C dm/host GAME=010059D020C26000 dmhost clean on Apple M6, macOS 26.6 (windowed run through the app's bundled dmhost).
  • MARVEL Cosmic Invasion: sprites visible at 60 fps, zero [RED] in the run log.
  • Docs: entry in docs/reference/rendering.md (docs_symptoms.py regenerated; test_docs.py 6/6).

Not checked

  • No other Vulkan game exercises vkCmdSetBlendConstants locally; static-blend pipelines are unaffected (p->blend is still what the create info held).

…ic Invasion)

SDL_GPU resolves every Vulkan entry point through vkGetDeviceProcAddr and calls some of them unchecked: lookups the
host did not implement returned null and the game crashed on a blr to 0 right after 'Setting backbuffer'. The
lookup now finds the calls SDL_GPU uses: vkCmdSetBlendConstants, vkCmdSetDepthBias, vkCmdSetDepthBounds,
vkCmdClearAttachments, vkCmdResolveImage, vkCmdDispatch, vkCmdDispatchIndirect, vkCmdDrawIndirect,
vkCmdDrawIndexedIndirect, vkCreateComputePipelines and the VK_EXT_debug_utils entry points — no-ops that keep the
call landing somewhere real until each gets its Metal implementation.

vkCmdBlitImage is real: an unscaled same-format region goes through the blit encoder like vkCmdCopyImage, and what
a copy cannot do — a blit between different formats, scaled or flipped — is drawn with the draw_tex builtin, which
samples the source through a fullscreen triangle whose linear mapping takes a flip into account on its own. This
was the black screen: SDL_GPU renders its frame to an R8G8B8A8 texture and blits it into the B8G8R8A8 swapchain
image, which no Metal copy can do.

Checked: dmhost builds; MARVEL Cosmic Invasion plays its intro video in a window at 60 FPS with audio (was a black
screen before).
…vasion)

Symptom: sprites drawn with CONSTANT_COLOR/CONSTANT_ALPHA blend factors
were invisible (the player's characters and enemies in MARVEL's stages);
the run log showed "[RED] dynamic state 4 not implemented".

Cause: VK_DYNAMIC_STATE_BLEND_CONSTANTS makes the blend colour a
command-buffer value set by vkCmdSetBlendConstants, which the layer
listed as a no-op; the encoder kept its zero default, so the factor
multiplied the source to nothing.

Fix: the command is recorded (C_BLEND) and replayed into the encoder's
blend colour; a pipeline declaring the dynamic state takes the command
buffer's value, others keep their own. Checked: MARVEL's sprites draw;
the log has no [RED] left.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation vulkan Vulkan on Metal (dm/gfx/vk)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant