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

vkGetQueryPoolResults fails when using VK_QUERY_RESULT_WITH_AVAILABILITY_BIT #922

Closed
Grimelios opened this issue Jun 5, 2024 · 1 comment

Comments

@Grimelios
Copy link

When calling vkGetQueryPoolResults using the VK_QUERY_RESULT_WITH_AVAILABILITY_BIT bit, proper usage requires passing in twice the usual data size (and specifying twice the stride) in order to account for availability values. For example, this call (which doesn't use VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) works like a charm:

let mut data = vec![0_u64; 2];

unsafe
{
    device.get_query_pool_results(
        query_pool, 
        0, 
        2, 
        &mut data, 
        QueryResultFlags::TYPE_64)?;
}

let elapsed = (data[1] - data[0]) as f32 * timestamp_period / 1000000.0;

An equivalent example using VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is below. Note the doubled vector length, inclusion of QueryResultFlags::WITH_AVAILABILITY, and checking availability prior to utilizing query results.

let mut data = vec![0_u64; 4];

unsafe
{
    device.get_query_pool_results(
        query_pool, 
        0, 
        2, 
        &mut data, 
        QueryResultFlags::TYPE_64 | QueryResultFlags::WITH_AVAILABILITY)?;
}

if data[1] != 0
{
    let elapsed = (data[2] - data[0]) as f32 * timestamp_period / 1000000.0;
}

However, using ash, this call fails with a Vulkan validation message stating queryPool specified dataSize 16 which is incompatible with the specified query type and options.

The culprit is actually the stride parameter of vkGetQueryPoolResults. ash passes stride as mem::size_of::<T>() as _, which in this example is 8 (T is u64). With VK_QUERY_RESULT_WITH_AVAILABILITY_BIT, however, that stride should actually be 16, which accounts for interleaved query results and availabilities. This can be worked around by calling the relevant function directly:

let result = unsafe
{
    (device.fp_v1_0().get_query_pool_results)(
        device.handle(), 
        query_pool, 
        0, 
        2, 
        mem::size_of::<u64>() * data.len(), 
        data.as_mut_ptr() as *mut _,
        mem::size_of::<u64>() * 2,
        QueryResultFlags::TYPE_64 | QueryResultFlags::WITH_AVAILABILITY).result()
};

A non-breaking solution would be to double the stride if QueryResultFlags::WITH_AVAILABILITY is set. A breaking solution would be to modify the get_query_pool_results signature to include stride.

@MarijnS95
Copy link
Collaborator

Duplicate of #100 (comment), #639 (comment), #644 and #900.

@MarijnS95 MarijnS95 closed this as not planned Won't fix, can't repro, duplicate, stale Jun 5, 2024
@ash-rs ash-rs locked as spam and limited conversation to collaborators Jun 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants