Vulkan-ValidationLayers icon indicating copy to clipboard operation
Vulkan-ValidationLayers copied to clipboard

Memory Issues in ValidationStateTracker::PostCallRecordCmdPushConstants

Open WalkerWhite opened this issue 9 months ago • 4 comments

Environment:

  • OS: macOS Sonoma 14.7.4
  • GPU and driver version: Apple M2 Max (MoltenVK 1.2.296)
  • SDK or header version if building from repo: API version 1.3.290 built from repo
  • Options enabled (synchronization, best practices, etc.): Release build from CMake for macOS

Describe the Issue

I have noticed a very slight but consistent memory climb when running a simple Vulkan demo with validation layers. This demo is a test of push constants that flips a single int-valued push constant twice a frame to switch between two textures.

Drilling down into the malloc traces, I discovered that the primary culprit for this memory usage is ValidationStateTracker::PostCallRecordCmdPushConstants in the validation layer (I build this from source so I can have a xcframework instead of the dylib provided by LunarG).

The method PostCallRecordCmdPushConstants records push constants in an append-only vector every time vkCmdPushConstants is called. It is only cleared in two cases: ResetPushConstantRangesLayoutIfIncompatible and UnbindResources. Since I never unbind resources (this is a demo with static vertex and index buffers), this is never called. So the vector cb_state->push_constant_data_chunks fills up forever.

Is this intended behavior?

WalkerWhite avatar Apr 04 '25 00:04 WalkerWhite

So tracking Push Constants has been an constant evolution of trial and error it feels, but we have this code

    // Always add submitted push constant values, even if the same data is already stored.
    // Storing duplicated data, or data submitted by one vkCmdPushConstants call
    // and overridden by a subsequent one is not a problem.
    // push_constant_data_chunks is intended to be parsed from 0 to N,
    // thus going through the history in order, so even though it is
    // possibly suboptimal push constant data is correct.
    cb_state->push_constant_data_chunks.emplace_back(push_constant_data);

and from what you posted, push_constant_data_chunks is the problem

Looking at this, this is only used for Best Practice check and to restore push constants we disturb in GPU-AV

The GPU-AV one, we don't need to track this

The Best Practice, I still think we need to do this, but this can actually be fully moved over so unless you turn on Best Practice, you will not see the increase allocation occur

spencer-lunarg avatar Apr 04 '25 02:04 spencer-lunarg

@WalkerWhite I am still not sure what your demo is doing? How are you calling vkCmdPushConstants endlessly without ever resetting the command buffer, this is only for recording of the command buffer... how many calls vkCmdPushConstants are you making?

spencer-lunarg avatar Apr 04 '25 02:04 spencer-lunarg

@spencer-lunarg Oh, wait. I see now. I am calling

vkResetCommandBuffer(_primary, /*VkCommandBufferResetFlagBits*/ 0);

which is what is shown in just about every tutorial online. According to documentation, that is why resources are not being freed. I guess I should be doing VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT

WalkerWhite avatar Apr 04 '25 04:04 WalkerWhite

no, the issue is you have an old VVL version (1.3.290)

https://github.com/KhronosGroup/Vulkan-ValidationLayers/pull/8635

we fixed this and if you grab the latest VVL you should see the fix

spencer-lunarg avatar Apr 04 '25 11:04 spencer-lunarg

closing, this should be fixed in the latest SDK releases, if not, will be happy to reopen

spencer-lunarg avatar Jul 02 '25 20:07 spencer-lunarg