Skip to content

Instantly share code, notes, and snippets.

@Neo-Zhixing
Created May 31, 2023 02:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Neo-Zhixing/992a0e789e34b59285026dd8161b9112 to your computer and use it in GitHub Desktop.
Save Neo-Zhixing/992a0e789e34b59285026dd8161b9112 to your computer and use it in GitHub Desktop.
AMD Descriptor Pool alignment behavior for inline uniform block
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