Don't declare colorWriteEnable dynamic state on depth-only pipelines (#160)

fix(gpu): drop colorWriteEnable dynamic state on depth-only pipelines

Pipelines were created with VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT
unconditionally on non-Apple platforms, but the draw path only calls
vkCmdSetColorWriteEnableEXT when there is at least one color attachment.
A depth-only draw therefore reached vkCmdDrawIndexed with the dynamic
state declared and never set, which violates
VUID-vkCmdDrawIndexed-None-07749.

With validation enabled the error is fatal, so any title that issues a
depth-only pass aborts. The launcher enables validation by default
(vulkan_validation_enabled = true), so this is the default configuration:
PAC-MAN WORLD Re-PAC crashes from the launcher while the same build runs
normally with --vulkan-validation false.

Gate the declaration on the same color_count the draw path uses. Both
sides read state.color_count from the same draw, so the two conditions
are now identical by construction.
This commit is contained in:
DeathWhispers
2026-08-08 02:21:18 -04:00
committed by GitHub
parent 87428d7a4b
commit 7ff9e4907f
@@ -953,11 +953,17 @@ void CreatePipelineInternal(
vk::DynamicState::eStencilReference, vk::DynamicState::eStencilReference,
vk::DynamicState::eStencilWriteMask, vk::DynamicState::eStencilWriteMask,
#if !defined(__APPLE__) #if !defined(__APPLE__)
// Keep last so depth-only pipelines can omit this dynamic state.
vk::DynamicState::eColorWriteEnableEXT, // unsupported by MoltenVK; static mask instead vk::DynamicState::eColorWriteEnableEXT, // unsupported by MoltenVK; static mask instead
#endif #endif
}; };
const auto dynamic_states_count = auto dynamic_states_count =
static_cast<uint32_t>(sizeof(dynamic_states) / sizeof(dynamic_states[0])); static_cast<uint32_t>(sizeof(dynamic_states) / sizeof(dynamic_states[0]));
#if !defined(__APPLE__)
if (static_params.color_count == 0) {
dynamic_states_count--;
}
#endif
vk::PipelineDynamicStateCreateInfo dynamic_state {}; vk::PipelineDynamicStateCreateInfo dynamic_state {};
dynamic_state.sType = vk::StructureType::ePipelineDynamicStateCreateInfo; dynamic_state.sType = vk::StructureType::ePipelineDynamicStateCreateInfo;