Skip to content

WGPU leaks the implicit PLL of pipeline layouts #5029

Closed
@DevJac

Description

This 300 line graphics application leaks memory: https://github.com/DevJac/life_sim/blob/36a55a1a4762bb140d1fed2f04011e7f3d030203/src/main.rs

The code is in a single file, which I've also attached to this issue if needed for future reference.
main.txt

My render code is unusual because it recreates the pipeline each frame, I'm learning so I've been focused on forward progress rather than optimal code.

After 10,123 frames rendered, I get the following report from Instance:

Instance report: GlobalReport { surfaces: StorageReport { num_occupied: 1, num_vacant: 0, num_error: 0, element_size: 568 }, vulkan: Some(HubReport { adapters: StorageReport { num_occupied: 1, num_vacant: 0, num_error: 0, element_size: 1880 }, devices: StorageReport { num_occupied: 1, num_vacant: 0, num_error: 0, element_size: 12008 }, pipeline_layouts: StorageReport { num_occupied: 10123, num_vacant: 0, num_error: 0, element_size: 176 }, shader_modules: StorageReport { num_occupied: 0, num_vacant: 1, num_error: 0, element_size: 744 }, bind_group_layouts: StorageReport { num_occupied: 1, num_vacant: 0, num_error: 80983, element_size: 240 }, bind_groups: StorageReport { num_occupied: 0, num_vacant: 1, num_error: 0, element_size: 312 }, command_buffers: StorageReport { num_occupied: 0, num_vacant: 1, num_error: 0, element_size: 1416 }, render_bundles: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 904 }, render_pipelines: StorageReport { num_occupied: 0, num_vacant: 1, num_error: 0, element_size: 512 }, compute_pipelines: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 256 }, query_sets: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 48 }, buffers: StorageReport { num_occupied: 2, num_vacant: 2, num_error: 0, element_size: 304 }, textures: StorageReport { num_occupied: 0, num_vacant: 2, num_error: 0, element_size: 784 }, texture_views: StorageReport { num_occupied: 0, num_vacant: 2, num_error: 0, element_size: 208 }, samplers: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 48 } }), gl: Some(HubReport { adapters: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 272 }, devices: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 5544 }, pipeline_layouts: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 200 }, shader_modules: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 768 }, bind_group_layouts: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 152 }, bind_groups: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 248 }, command_buffers: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 4168 }, render_bundles: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 904 }, render_pipelines: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 672 }, compute_pipelines: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 256 }, query_sets: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 64 }, buffers: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 192 }, textures: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 672 }, texture_views: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 184 }, samplers: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 40 } }) }

or formatted:

GlobalReport {
	     surfaces: StorageReport { num_occupied: 1, num_vacant: 0, num_error: 0, element_size: 568 },
	     vulkan: Some(HubReport {
	     	     adapters: StorageReport { num_occupied: 1, num_vacant: 0, num_error: 0, element_size: 1880 },
		     devices: StorageReport { num_occupied: 1, num_vacant: 0, num_error: 0, element_size: 12008 },
		     pipeline_layouts: StorageReport { num_occupied: 10123, num_vacant: 0, num_error: 0, element_size: 176 },
		     shader_modules: StorageReport { num_occupied: 0, num_vacant: 1, num_error: 0, element_size: 744 },
		     bind_group_layouts: StorageReport { num_occupied: 1, num_vacant: 0, num_error: 80983, element_size: 240 },
		     bind_groups: StorageReport { num_occupied: 0, num_vacant: 1, num_error: 0, element_size: 312 },
		     command_buffers: StorageReport { num_occupied: 0, num_vacant: 1, num_error: 0, element_size: 1416 },
		     render_bundles: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 904 },
		     render_pipelines: StorageReport { num_occupied: 0, num_vacant: 1, num_error: 0, element_size: 512 },
		     compute_pipelines: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 256 },
		     query_sets: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 48 },
		     buffers: StorageReport { num_occupied: 2, num_vacant: 2, num_error: 0, element_size: 304 },
		     textures: StorageReport { num_occupied: 0, num_vacant: 2, num_error: 0, element_size: 784 },
		     texture_views: StorageReport { num_occupied: 0, num_vacant: 2, num_error: 0, element_size: 208 },
		     samplers: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 48 } }),
	     gl: Some(HubReport {
	     	     adapters: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 272 },
		     devices: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 5544 },
		     pipeline_layouts: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 200 },
		     shader_modules: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 768 },
		     bind_group_layouts: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 152 },
		     bind_groups: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 248 },
		     command_buffers: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 4168 },
		     render_bundles: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 904 },
		     render_pipelines: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 672 },
		     compute_pipelines: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 256 },
		     query_sets: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 64 },
		     buffers: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 192 },
		     textures: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 672 },
		     texture_views: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 184 },
		     samplers: StorageReport { num_occupied: 0, num_vacant: 0, num_error: 0, element_size: 40 } })
}

Notice the number of pipeline_layouts equals the number of frames rendered. This appears to be the memory leak. The counts of all other objects are low.

Metadata

Assignees

Labels

type: bugSomething isn't working

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions