Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aggressive GC? #94

Open
gibki opened this issue Oct 18, 2024 · 3 comments
Open

Aggressive GC? #94

gibki opened this issue Oct 18, 2024 · 3 comments

Comments

@gibki
Copy link

gibki commented Oct 18, 2024

My program started exploding randomly after I refactored this:

vertex_stage = vk.VkPipelineShaderStageCreateInfo(
    stage=vk.VK_SHADER_STAGE_VERTEX_BIT,
    module=vertex_shader,
    pName='main',
)
pipeline = vk.vkCreateGraphicsPipelines(
    pStages=[vertex_stage]
)

Into this:

pipeline = vk.vkCreateGraphicsPipelines(
    pStages=[
        vk.VkPipelineShaderStageCreateInfo(
            stage=vk.VK_SHADER_STAGE_VERTEX_BIT,
            module=vertex_shader,
            pName='main',
        )
    ]
)

The validation layer is (sometimes) reporting
VUID-VkPipelineShaderStageCreateInfo-pName-00707(ERROR / SPEC): msgNum: -1282697375 - Validation Error: [ VUID-VkPipelineShaderStageCreateInfo-pName-00707 ] | MessageID = 0xb38b9761 | vkCreateGraphicsPipelines(): pCreateInfos[0].pStages[0].pName `` entrypoint not found for stage VK_SHADER_STAGE_VERTEX_BIT. The Vulkan spec states: pName must be the name of an OpEntryPoint in module with an execution model that matches stage (https://vulkan.lunarg.com/doc/view/1.3.296.0/windows/1.3-extensions/vkspec.html#VUID-VkPipelineShaderStageCreateInfo-pName-00707)

I think the VkPipelineShaderStageCreateInfo object and the underlying string get garbage collected before the wrapping call to vkCreateGraphicsPipelines happens.

I don't know if this is a bug, maybe I misunderstand object lifetimes, but it's definitely perplexing.

@gibki
Copy link
Author

gibki commented Oct 19, 2024

You can reproduce this with this snippet:

import vulkan as vk

for i in range(1000):
    pipeline_info = vk.VkGraphicsPipelineCreateInfo(
        pStages=[vk.VkPipelineShaderStageCreateInfo(
            pName='main'
        )]
    )
    assert vk.ffi.string(pipeline_info.pStages[0].pName) == b'main'
    vk.ffi.new('VkPipeline[%d]' % 1)  # trigger GC
    assert vk.ffi.string(pipeline_info.pStages[0].pName) == b'main' # will fail eventually

The issue is that the cdata string object is only held up by a weak reference, keyed on the result of vk.VkPipelineShaderStageCreateInfo. When vk.VkGraphicsPipelineCreateInfo converts the list of stages in creates a new array and copies over the data, but the object holding up the string goes out of scope.

This is quick and dirty modification to _cast_ptr2 to rekey the reference:

if isinstance(x, list):
    iterable_references = []
    for item in x:
        item_references = _weakkey_dict.get(item)
        if item_references:
            iterable_references.append(item_references)
    if iterable_references:
        _weakkey_dict[ret] = iterable_references

@realitix
Copy link
Owner

Hello @gibki, your assomption is good. Behind the scene, cffi is used and clean the ressources. Could you do a patch for that ?

@gibki
Copy link
Author

gibki commented Oct 19, 2024

https://github.com/realitix/vulkan/pull/95

I only started checking out Vulkan so I don't have a big application on hand, but it seems to work for the demos.

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

No branches or pull requests

2 participants