Created
May 31, 2023 02:05
-
-
Save Neo-Zhixing/992a0e789e34b59285026dd8161b9112 to your computer and use it in GitHub Desktop.
AMD Descriptor Pool alignment behavior for inline uniform block
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use ash::vk; | |
fn main() { | |
unsafe { | |
run(); | |
} | |
} | |
/// Vulkan specification says that the size of the inline uniform block must be multiples of 4. | |
/// However, AMD seems to allocate this with 8 byte alignment. | |
/// On my AMD 7735HS IGPU, using size = 8, 16, 24, 32... passes the test. | |
/// using size = 4, 12, 20, 28... fails the test with ERROR_OUT_OF_POOL_MEMORY | |
const INLINE_UNIFORM_SIZE: u32 = 24; | |
const INLINE_UNIFORM_BLOCK_COUNT: u32 = 2; | |
unsafe fn run() { | |
let entry = ash::Entry::load().unwrap(); | |
let instance = entry | |
.create_instance( | |
&vk::InstanceCreateInfo { | |
p_application_info: &vk::ApplicationInfo { | |
api_version: vk::make_api_version(0, 1, 3, 0), | |
..Default::default() | |
}, | |
..Default::default() | |
}, | |
None, | |
) | |
.unwrap(); | |
let pdevice = instance.enumerate_physical_devices().unwrap()[0]; | |
let pdevice_properties = instance.get_physical_device_properties(pdevice); | |
let device_name = std::ffi::CStr::from_ptr(pdevice_properties.device_name.as_ptr() as _); | |
println!("Using device: {}", device_name.to_str().unwrap()); | |
let mut v13_features = vk::PhysicalDeviceVulkan13Features { | |
inline_uniform_block: vk::TRUE, | |
..Default::default() | |
}; | |
let features = vk::PhysicalDeviceFeatures2::builder() | |
.push_next(&mut v13_features) | |
.build(); | |
let device = instance | |
.create_device( | |
pdevice, | |
&vk::DeviceCreateInfo { | |
p_next: &features as *const _ as *const _, | |
queue_create_info_count: 1, | |
p_queue_create_infos: &vk::DeviceQueueCreateInfo { | |
queue_family_index: 0, | |
queue_count: 1, | |
p_queue_priorities: &1.0, | |
..Default::default() | |
}, | |
..Default::default() | |
}, | |
None, | |
) | |
.unwrap(); | |
let desc_set_layout = device | |
.create_descriptor_set_layout( | |
&vk::DescriptorSetLayoutCreateInfo { | |
flags: vk::DescriptorSetLayoutCreateFlags::empty(), | |
binding_count: 1, | |
p_bindings: [vk::DescriptorSetLayoutBinding { | |
binding: 0, | |
descriptor_type: vk::DescriptorType::INLINE_UNIFORM_BLOCK, | |
descriptor_count: INLINE_UNIFORM_SIZE, | |
stage_flags: vk::ShaderStageFlags::COMPUTE, | |
..Default::default() | |
}] | |
.as_slice() | |
.as_ptr(), | |
..Default::default() | |
}, | |
None, | |
) | |
.unwrap(); | |
let descriptor_pool = device | |
.create_descriptor_pool( | |
&vk::DescriptorPoolCreateInfo::builder() | |
.max_sets(INLINE_UNIFORM_BLOCK_COUNT) | |
.pool_sizes(&[vk::DescriptorPoolSize { | |
ty: vk::DescriptorType::INLINE_UNIFORM_BLOCK, | |
descriptor_count: INLINE_UNIFORM_SIZE * INLINE_UNIFORM_BLOCK_COUNT, | |
}]) | |
.push_next(&mut vk::DescriptorPoolInlineUniformBlockCreateInfo { | |
max_inline_uniform_block_bindings: 3, | |
..Default::default() | |
}), | |
None, | |
) | |
.unwrap(); | |
for _ in 0..INLINE_UNIFORM_BLOCK_COUNT { | |
device | |
.allocate_descriptor_sets(&vk::DescriptorSetAllocateInfo { | |
descriptor_pool, | |
descriptor_set_count: 1, | |
p_set_layouts: &desc_set_layout, | |
..Default::default() | |
}) | |
.unwrap()[0]; | |
} | |
println!("Test passed!"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment