Implement vkCreateImage

This commit is contained in:
msiglreith 2017-12-09 16:29:25 +01:00
parent 740cec2c9b
commit 468c42a3a2
5 changed files with 179 additions and 10 deletions

View file

@ -174,3 +174,85 @@ fn map_aspect(aspects: VkImageAspectFlags) -> image::AspectFlags {
}
flags
}
pub fn map_image_kind(
ty: VkImageType,
flags: VkImageCreateFlags,
extent: VkExtent3D,
array_layers: u32,
samples: VkSampleCountFlagBits,
) -> image::Kind {
debug_assert_ne!(array_layers, 0);
let is_cube = flags & VkImageCreateFlagBits::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT as u32 != 0;
assert!(!is_cube || array_layers % 6 == 0);
match ty {
VkImageType::VK_IMAGE_TYPE_1D => {
image::Kind::D1(extent.width as _)
}
VkImageType::VK_IMAGE_TYPE_1D => {
image::Kind::D1Array(extent.width as _, array_layers as _)
}
VkImageType::VK_IMAGE_TYPE_2D if array_layers == 1 => {
image::Kind::D2(extent.width as _, extent.height as _, map_aa_mode(samples))
}
VkImageType::VK_IMAGE_TYPE_2D if is_cube && array_layers == 6 => {
image::Kind::Cube(extent.width as _)
}
VkImageType::VK_IMAGE_TYPE_2D if is_cube => {
image::Kind::CubeArray(extent.width as _, (array_layers / 6) as _)
}
VkImageType::VK_IMAGE_TYPE_2D => {
image::Kind::D2Array(
extent.width as _,
extent.height as _,
array_layers as _,
map_aa_mode(samples),
)
}
VkImageType::VK_IMAGE_TYPE_3D => {
image::Kind::D3(extent.width as _, extent.height as _, extent.depth as _)
}
_ => unimplemented!(),
}
}
fn map_aa_mode(samples: VkSampleCountFlagBits) -> image::AaMode {
use VkSampleCountFlagBits::*;
match samples {
VK_SAMPLE_COUNT_1_BIT => image::AaMode::Single,
_ => image::AaMode::Multi(samples as _),
}
}
pub fn map_image_usage(usage: VkImageUsageFlags) -> image::Usage {
let mut flags = image::Usage::empty();
if usage & VkImageUsageFlagBits::VK_IMAGE_USAGE_TRANSFER_SRC_BIT as u32 != 0 {
flags |= image::Usage::TRANSFER_SRC;
}
if usage & VkImageUsageFlagBits::VK_IMAGE_USAGE_TRANSFER_DST_BIT as u32 != 0 {
flags |= image::Usage::TRANSFER_DST;
}
if usage & VkImageUsageFlagBits::VK_IMAGE_USAGE_SAMPLED_BIT as u32 != 0 {
flags |= image::Usage::SAMPLED;
}
if usage & VkImageUsageFlagBits::VK_IMAGE_USAGE_STORAGE_BIT as u32 != 0 {
flags |= image::Usage::STORAGE;
}
if usage & VkImageUsageFlagBits::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT as u32 != 0 {
flags |= image::Usage::COLOR_ATTACHMENT;
}
if usage & VkImageUsageFlagBits::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT as u32 != 0 {
flags |= image::Usage::DEPTH_STENCIL_ATTACHMENT;
}
if usage & VkImageUsageFlagBits::VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT as u32 != 0 {
unimplemented!()
}
if usage & VkImageUsageFlagBits::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT as u32 != 0 {
unimplemented!()
}
flags
}

View file

@ -1,6 +1,7 @@
use super::*;
use std::mem;
use std::ops::Deref;
#[inline]
pub extern fn gfxCreateInstance(
@ -410,11 +411,27 @@ extern "C" {
pub fn vkDestroyBufferView(device: VkDevice, bufferView: VkBufferView,
pAllocator: *const VkAllocationCallbacks);
}
extern "C" {
pub fn vkCreateImage(device: VkDevice,
pCreateInfo: *const VkImageCreateInfo,
pAllocator: *const VkAllocationCallbacks,
pImage: *mut VkImage) -> VkResult;
#[inline]
pub extern fn gfxCreateImage(
gpu: VkDevice,
pCreateInfo: *const VkImageCreateInfo,
pAllocator: *const VkAllocationCallbacks,
pImage: *mut VkImage,
) -> VkResult {
let info = unsafe { &*pCreateInfo };
assert_eq!(info.sharingMode, VkSharingMode::VK_SHARING_MODE_EXCLUSIVE); // TODO
assert_eq!(info.tiling, VkImageTiling::VK_IMAGE_TILING_OPTIMAL); // TODO
assert_eq!(info.initialLayout, VkImageLayout::VK_IMAGE_LAYOUT_UNDEFINED); // TODO
let image = gpu.device.create_image(
conv::map_image_kind(info.imageType, info.flags, info.extent, info.arrayLayers, info.samples),
info.mipLevels as _,
conv::map_format(info.format),
conv::map_image_usage(info.usage),
).expect("Error on creating image");
unsafe { *pImage = Handle::new(Image::Unbound(image)); }
VkResult::VK_SUCCESS
}
extern "C" {
pub fn vkDestroyImage(device: VkDevice, image: VkImage,
@ -437,10 +454,16 @@ pub extern fn gfxCreateImageView(
assert!(info.subresourceRange.levelCount != VK_REMAINING_MIP_LEVELS as _); // TODO
assert!(info.subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS as _); // TODO
let image = match *info.image.deref() {
Image::Image(ref image) => image,
// Non-sparse images must be bound prior.
Image::Unbound(_) => panic!("Can't create view for unbound image"),
};
let view = gpu
.device
.create_image_view(
&info.image,
image,
conv::map_format(info.format),
conv::map_swizzle(info.components),
conv::map_subresource_range(info.subresourceRange),
@ -1097,7 +1120,7 @@ pub extern fn gfxCreateSwapchainKHR(
let images = match backbuffers {
hal::Backbuffer::Images(images) => {
images.into_iter().map(|image| Handle::new(image)).collect()
images.into_iter().map(|image| Handle::new(Image::Image(image))).collect()
},
hal::Backbuffer::Framebuffer(_) => {
panic!("Expected backbuffer images. Backends returning only framebuffers are not supported!")

View file

@ -27,7 +27,12 @@ pub type VkDevice = Handle<hal::Gpu<B>>;
pub type VkCommandPool = Handle<<B as hal::Backend>::CommandPool>;
pub type VkCommandBuffer = Handle<<B as hal::Backend>::CommandBuffer>;
pub type VkImage = Handle<<B as hal::Backend>::Image>;
pub enum Image<B: hal::Backend> {
Image(B::Image),
Unbound(B::UnboundImage),
}
pub type VkImage = Handle<Image<B>>;
pub type VkImageView = Handle<<B as hal::Backend>::ImageView>;
//NOTE: all *KHR types have to be pure `Handle` things for compatibility with

View file

@ -56,7 +56,15 @@ pub extern fn vkDestroyDevice(
) {
gfxDestroyDevice(device, pAllocator)
}
#[no_mangle]
pub extern fn vkCreateImage(
device: VkDevice,
pCreateInfo: *const VkImageCreateInfo,
pAllocator: *const VkAllocationCallbacks,
pImage: *mut VkImage,
) -> VkResult {
gfxCreateImage(device, pCreateInfo, pAllocator, pImage)
}
#[no_mangle]
pub extern fn vkCreateImageView(
device: VkDevice,

View file

@ -48,8 +48,11 @@ int main() {
return -1;
}
const uint32_t width = 800;
const uint32_t height = 600;
// Window initialization
Config config = { 10, 10, 800, 600 };
Config config = { 10, 10, width, height };
Window window = new_window(config);
VkSurfaceKHR surface;
@ -217,6 +220,54 @@ int main() {
return -1;
}
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
image_info.pNext = NULL;
image_info.imageType = VK_IMAGE_TYPE_2D;
image_info.format = depth_format;
image_info.extent.width = width;
image_info.extent.height = height;
image_info.extent.depth = 1;
image_info.mipLevels = 1;
image_info.arrayLayers = 1;
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
image_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
image_info.queueFamilyIndexCount = 0;
image_info.pQueueFamilyIndices = NULL;
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
image_info.flags = 0;
VkMemoryAllocateInfo mem_alloc = {};
mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
mem_alloc.pNext = NULL;
mem_alloc.allocationSize = 0;
mem_alloc.memoryTypeIndex = 0;
VkImageViewCreateInfo view_info = {};
view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
view_info.pNext = NULL;
view_info.image = VK_NULL_HANDLE;
view_info.format = depth_format;
view_info.components.r = VK_COMPONENT_SWIZZLE_R;
view_info.components.g = VK_COMPONENT_SWIZZLE_G;
view_info.components.b = VK_COMPONENT_SWIZZLE_B;
view_info.components.a = VK_COMPONENT_SWIZZLE_A;
view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
view_info.subresourceRange.baseMipLevel = 0;
view_info.subresourceRange.levelCount = 1;
view_info.subresourceRange.baseArrayLayer = 0;
view_info.subresourceRange.layerCount = 1;
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_info.flags = 0;
VkMemoryRequirements mem_reqs;
/* Create image */
VkImage depth_image = 0;
res = vkCreateImage(device, &image_info, NULL, &depth_image);
printf("\tvkCreateImage: res=%d\n", res);
assert(!res);
VkCommandPool cmd_pool = 0;
VkCommandPoolCreateInfo cmd_pool_info = {};
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;