Store mip_levels and array_layers for images

This commit is contained in:
AIOOB 2018-05-14 18:05:05 +01:00
parent 0852322bb2
commit 00d3085901
3 changed files with 128 additions and 141 deletions

View file

@ -157,34 +157,7 @@ fn map_swizzle_component(
} }
} }
pub fn map_subresource_layers(subresource: VkImageSubresourceLayers) -> image::SubresourceLayers { pub fn map_aspect(aspects: VkImageAspectFlags) -> format::Aspects {
image::SubresourceLayers {
aspects: map_aspect(subresource.aspectMask),
level: subresource.mipLevel as _,
layers: subresource.baseArrayLayer as _
..(subresource.baseArrayLayer + subresource.layerCount) as _,
}
}
pub fn map_subresource_range(subresource: VkImageSubresourceRange) -> image::SubresourceRange {
image::SubresourceRange {
aspects: map_aspect(subresource.aspectMask),
levels: subresource.baseMipLevel as _
.. if subresource.levelCount as i32 == VK_REMAINING_MIP_LEVELS {
!0
} else {
(subresource.baseMipLevel + subresource.levelCount) as _
},
layers: subresource.baseArrayLayer as _
.. if subresource.layerCount as i32 == VK_REMAINING_ARRAY_LAYERS {
!0
} else {
(subresource.baseArrayLayer + subresource.layerCount) as _
},
}
}
fn map_aspect(aspects: VkImageAspectFlags) -> format::Aspects {
let mut flags = format::Aspects::empty(); let mut flags = format::Aspects::empty();
if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT as u32 != 0 { if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT as u32 != 0 {
flags |= format::Aspects::COLOR; flags |= format::Aspects::COLOR;

View file

@ -908,13 +908,13 @@ pub extern "C" fn gfxBindImageMemory(
let temp = unsafe { mem::zeroed() }; let temp = unsafe { mem::zeroed() };
*image = match mem::replace(&mut *image, temp) { *image = match mem::replace(&mut *image, temp) {
Image::Image(_) => panic!("An non-sparse image can only be bound once!"), Image::Image { .. } => panic!("An non-sparse image can only be bound once!"),
Image::Unbound(unbound) => { Image::Unbound { raw, mip_levels, array_layers } => {
Image::Image( Image::Image {
gpu.device raw: gpu.device.bind_image_memory(&memory, memoryOffset, raw).unwrap(), // TODO
.bind_image_memory(&memory, memoryOffset, unbound) mip_levels,
.unwrap() // TODO array_layers,
) }
} }
}; };
@ -944,8 +944,8 @@ pub extern "C" fn gfxGetImageMemoryRequirements(
pMemoryRequirements: *mut VkMemoryRequirements, pMemoryRequirements: *mut VkMemoryRequirements,
) { ) {
let req = match *image { let req = match *image {
Image::Image(_) => unimplemented!(), Image::Image { .. } => unimplemented!(),
Image::Unbound(ref image) => gpu.device.get_image_requirements(image), Image::Unbound { ref raw, .. } => gpu.device.get_image_requirements(raw),
}; };
*unsafe { &mut *pMemoryRequirements } = VkMemoryRequirements { *unsafe { &mut *pMemoryRequirements } = VkMemoryRequirements {
@ -1263,7 +1263,11 @@ pub extern "C" fn gfxCreateImage(
.expect("Error on creating image"); .expect("Error on creating image");
unsafe { unsafe {
*pImage = Handle::new(Image::Unbound(image)); *pImage = Handle::new(Image::Unbound {
raw: image,
mip_levels: info.mipLevels,
array_layers: info.arrayLayers,
});
} }
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
@ -1274,8 +1278,8 @@ pub extern "C" fn gfxDestroyImage(
_pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
match image.unbox() { match image.unbox() {
Some(Image::Image(image)) => gpu.device.destroy_image(image), Some(Image::Image { raw, .. }) => gpu.device.destroy_image(raw),
Some(Image::Unbound(_)) => { Some(Image::Unbound { .. }) => {
warn!("Trying to destroy a non-bound image, ignoring"); warn!("Trying to destroy a non-bound image, ignoring");
} }
None => {} None => {}
@ -1301,18 +1305,15 @@ pub extern "C" fn gfxCreateImageView(
assert!(info.subresourceRange.levelCount != VK_REMAINING_MIP_LEVELS as _); // TODO assert!(info.subresourceRange.levelCount != VK_REMAINING_MIP_LEVELS as _); // TODO
assert!(info.subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS as _); // TODO assert!(info.subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS as _); // TODO
let image = match *info.image { // Non-sparse images must be bound prior.
Image::Image(ref image) => image, let image = info.image.expect("Can't create view for unbound 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( let view = gpu.device.create_image_view(
image, image,
conv::map_view_kind(info.viewType), conv::map_view_kind(info.viewType),
conv::map_format(info.format).unwrap(), conv::map_format(info.format).unwrap(),
conv::map_swizzle(info.components), conv::map_swizzle(info.components),
conv::map_subresource_range(info.subresourceRange), info.image.map_subresource_range(info.subresourceRange),
); );
match view { match view {
@ -2248,11 +2249,8 @@ pub extern "C" fn gfxUpdateDescriptorSets(
Some(buffer.offset + buffer.range) Some(buffer.offset + buffer.range)
}; };
pso::Descriptor::Buffer( pso::Descriptor::Buffer(
match *buffer.buffer { // Non-sparse buffer need to be bound to device memory.
Buffer::Buffer(ref buf) => buf, buffer.buffer.expect("Buffer needs to be bound"),
// Non-sparse buffer need to be bound to device memory.
Buffer::Unbound(_) => panic!("Buffer needs to be bound"),
},
Some(buffer.offset) .. end, Some(buffer.offset) .. end,
) )
}) })
@ -2796,10 +2794,7 @@ pub extern "C" fn gfxCmdBindIndexBuffer(
) { ) {
commandBuffer.bind_index_buffer( commandBuffer.bind_index_buffer(
IndexBufferView { IndexBufferView {
buffer: match *buffer { buffer: buffer.expect("Bound index buffer expected."),
Buffer::Buffer(ref b) => b,
Buffer::Unbound(_) => panic!("Bound index buffer expected."),
},
offset, offset,
index_type: conv::map_index_type(indexType), index_type: conv::map_index_type(indexType),
} }
@ -2825,10 +2820,7 @@ pub extern "C" fn gfxCmdBindVertexBuffers(
.into_iter() .into_iter()
.zip(offsets.into_iter()) .zip(offsets.into_iter())
.map(|(buffer, offset)| { .map(|(buffer, offset)| {
let buffer = match **buffer { let buffer = buffer.expect("Non-sparse buffers need to be bound to device memory.");
Buffer::Buffer(ref buffer) => buffer,
Buffer::Unbound(_) => panic!("Non-sparse buffers need to be bound to device memory."),
};
(buffer, *offset as _) (buffer, *offset as _)
}) })
@ -2899,10 +2891,7 @@ pub extern "C" fn gfxCmdDispatchIndirect(
buffer: VkBuffer, buffer: VkBuffer,
offset: VkDeviceSize, offset: VkDeviceSize,
) { ) {
match *buffer { commandBuffer.dispatch_indirect(buffer.expect("Bound buffer expected!"), offset)
Buffer::Buffer(ref b) => commandBuffer.dispatch_indirect(b, offset),
Buffer::Unbound(_) => panic!("Bound buffer expected!"),
}
} }
#[inline] #[inline]
pub extern "C" fn gfxCmdCopyBuffer( pub extern "C" fn gfxCmdCopyBuffer(
@ -2923,14 +2912,8 @@ pub extern "C" fn gfxCmdCopyBuffer(
}); });
commandBuffer.copy_buffer( commandBuffer.copy_buffer(
match *srcBuffer { srcBuffer.expect("Bound src buffer expected!"),
Buffer::Buffer(ref src) => src, dstBuffer.expect("Bound dst buffer expected!"),
Buffer::Unbound(_) => panic!("Bound src buffer expected!"),
},
match *dstBuffer {
Buffer::Buffer(ref dst) => dst,
Buffer::Unbound(_) => panic!("Bound dst buffer expected!"),
},
regions, regions,
); );
} }
@ -2949,23 +2932,17 @@ pub extern "C" fn gfxCmdCopyImage(
} }
.iter() .iter()
.map(|r| com::ImageCopy { .map(|r| com::ImageCopy {
src_subresource: conv::map_subresource_layers(r.srcSubresource), src_subresource: srcImage.map_subresource_layers(r.srcSubresource),
src_offset: conv::map_offset(r.srcOffset), src_offset: conv::map_offset(r.srcOffset),
dst_subresource: conv::map_subresource_layers(r.dstSubresource), dst_subresource: dstImage.map_subresource_layers(r.dstSubresource),
dst_offset: conv::map_offset(r.dstOffset), dst_offset: conv::map_offset(r.dstOffset),
extent: conv::map_extent(r.extent), extent: conv::map_extent(r.extent),
}); });
commandBuffer.copy_image( commandBuffer.copy_image(
match *srcImage { srcImage.expect("Bound src image expected!"),
Image::Image(ref src) => src,
Image::Unbound(_) => panic!("Bound src image expected!"),
},
conv::map_image_layout(srcImageLayout), conv::map_image_layout(srcImageLayout),
match *dstImage { dstImage.expect("Bound dst image expected!"),
Image::Image(ref dst) => dst,
Image::Unbound(_) => panic!("Bound dst image expected!"),
},
conv::map_image_layout(dstImageLayout), conv::map_image_layout(dstImageLayout),
regions, regions,
); );
@ -2986,22 +2963,16 @@ pub extern "C" fn gfxCmdBlitImage(
} }
.iter() .iter()
.map(|r| com::ImageBlit { .map(|r| com::ImageBlit {
src_subresource: conv::map_subresource_layers(r.srcSubresource), src_subresource: srcImage.map_subresource_layers(r.srcSubresource),
src_bounds: conv::map_offset(r.srcOffsets[0]) .. conv::map_offset(r.srcOffsets[1]), src_bounds: conv::map_offset(r.srcOffsets[0]) .. conv::map_offset(r.srcOffsets[1]),
dst_subresource: conv::map_subresource_layers(r.dstSubresource), dst_subresource: dstImage.map_subresource_layers(r.dstSubresource),
dst_bounds: conv::map_offset(r.dstOffsets[0]) .. conv::map_offset(r.dstOffsets[1]), dst_bounds: conv::map_offset(r.dstOffsets[0]) .. conv::map_offset(r.dstOffsets[1]),
}); });
commandBuffer.blit_image( commandBuffer.blit_image(
match *srcImage { srcImage.expect("Bound src image expected!"),
Image::Image(ref src) => src,
Image::Unbound(_) => panic!("Bound src image expected!"),
},
conv::map_image_layout(srcImageLayout), conv::map_image_layout(srcImageLayout),
match *dstImage { dstImage.expect("Bound dst image expected!"),
Image::Image(ref dst) => dst,
Image::Unbound(_) => panic!("Bound dst image expected!"),
},
conv::map_image_layout(dstImageLayout), conv::map_image_layout(dstImageLayout),
conv::map_filter(filter), conv::map_filter(filter),
regions, regions,
@ -3024,20 +2995,14 @@ pub extern "C" fn gfxCmdCopyBufferToImage(
buffer_offset: r.bufferOffset, buffer_offset: r.bufferOffset,
buffer_width: r.bufferRowLength, buffer_width: r.bufferRowLength,
buffer_height: r.bufferImageHeight, buffer_height: r.bufferImageHeight,
image_layers: conv::map_subresource_layers(r.imageSubresource), image_layers: dstImage.map_subresource_layers(r.imageSubresource),
image_offset: conv::map_offset(r.imageOffset), image_offset: conv::map_offset(r.imageOffset),
image_extent: conv::map_extent(r.imageExtent), image_extent: conv::map_extent(r.imageExtent),
}); });
commandBuffer.copy_buffer_to_image( commandBuffer.copy_buffer_to_image(
match *srcBuffer { srcBuffer.expect("Bound buffer expected!"),
Buffer::Buffer(ref b) => b, dstImage.expect("Bound image expected!"),
Buffer::Unbound(_) => panic!("Bound buffer expected!"),
},
match *dstImage {
Image::Image(ref i) => i,
Image::Unbound(_) => panic!("Bound image expected!"),
},
conv::map_image_layout(dstImageLayout), conv::map_image_layout(dstImageLayout),
regions, regions,
); );
@ -3059,21 +3024,15 @@ pub extern "C" fn gfxCmdCopyImageToBuffer(
buffer_offset: r.bufferOffset, buffer_offset: r.bufferOffset,
buffer_width: r.bufferRowLength, buffer_width: r.bufferRowLength,
buffer_height: r.bufferImageHeight, buffer_height: r.bufferImageHeight,
image_layers: conv::map_subresource_layers(r.imageSubresource), image_layers: srcImage.map_subresource_layers(r.imageSubresource),
image_offset: conv::map_offset(r.imageOffset), image_offset: conv::map_offset(r.imageOffset),
image_extent: conv::map_extent(r.imageExtent), image_extent: conv::map_extent(r.imageExtent),
}); });
commandBuffer.copy_image_to_buffer( commandBuffer.copy_image_to_buffer(
match *srcImage { srcImage.expect("Bound image expected!"),
Image::Image(ref i) => i,
Image::Unbound(_) => panic!("Bound image expected!"),
},
conv::map_image_layout(srcImageLayout), conv::map_image_layout(srcImageLayout),
match *dstBuffer { dstBuffer.expect("Bound buffer expected!"),
Buffer::Buffer(ref b) => b,
Buffer::Unbound(_) => panic!("Bound buffer expected!"),
},
regions, regions,
); );
} }
@ -3086,10 +3045,7 @@ pub extern "C" fn gfxCmdUpdateBuffer(
pData: *const ::std::os::raw::c_void, pData: *const ::std::os::raw::c_void,
) { ) {
commandBuffer.update_buffer( commandBuffer.update_buffer(
match *dstBuffer { dstBuffer.expect("Bound buffer expected!"),
Buffer::Buffer(ref buf) => buf,
Buffer::Unbound(_) => panic!("Bound buffer expected!"),
},
dstOffset, dstOffset,
unsafe { unsafe {
slice::from_raw_parts(pData as _, dataSize as _) slice::from_raw_parts(pData as _, dataSize as _)
@ -3110,10 +3066,7 @@ pub extern "C" fn gfxCmdFillBuffer(
(Some(dstOffset), Some(dstOffset + size)) (Some(dstOffset), Some(dstOffset + size))
}; };
commandBuffer.fill_buffer( commandBuffer.fill_buffer(
match *dstBuffer { dstBuffer.expect("Bound buffer expected!"),
Buffer::Buffer(ref buf) => buf,
Buffer::Unbound(_) => panic!("Bound buffer expected!"),
},
range, range,
data, data,
); );
@ -3131,17 +3084,13 @@ pub extern "C" fn gfxCmdClearColorImage(
slice::from_raw_parts(pRanges, rangeCount as _) slice::from_raw_parts(pRanges, rangeCount as _)
}; };
commandBuffer.clear_image( commandBuffer.clear_image(
match *image { image.expect("Bound image expected!"),
Image::Image(ref image) => image,
Image::Unbound(_) => panic!("Bound image expected!"),
},
conv::map_image_layout(imageLayout), conv::map_image_layout(imageLayout),
unsafe { mem::transmute(*pColor) }, unsafe { mem::transmute(*pColor) },
unsafe { mem::zeroed() }, unsafe { mem::zeroed() },
subresource_ranges subresource_ranges
.iter() .iter()
.cloned() .map(|&range| image.map_subresource_range(range)),
.map(conv::map_subresource_range),
); );
} }
#[inline] #[inline]
@ -3157,17 +3106,13 @@ pub extern "C" fn gfxCmdClearDepthStencilImage(
slice::from_raw_parts(pRanges, rangeCount as _) slice::from_raw_parts(pRanges, rangeCount as _)
}; };
commandBuffer.clear_image( commandBuffer.clear_image(
match *image { image.expect("Bound image expected!"),
Image::Image(ref image) => image,
Image::Unbound(_) => panic!("Bound image expected!"),
},
conv::map_image_layout(imageLayout), conv::map_image_layout(imageLayout),
unsafe { mem::zeroed() }, unsafe { mem::zeroed() },
unsafe { mem::transmute(*pDepthStencil) }, unsafe { mem::transmute(*pDepthStencil) },
subresource_ranges subresource_ranges
.iter() .iter()
.cloned() .map(|&range| image.map_subresource_range(range)),
.map(conv::map_subresource_range),
); );
} }
#[inline] #[inline]
@ -3292,10 +3237,7 @@ pub extern "C" fn gfxCmdPipelineBarrier(
.iter() .iter()
.map(|b| memory::Barrier::Buffer { .map(|b| memory::Barrier::Buffer {
states: conv::map_buffer_access(b.srcAccessMask) .. conv::map_buffer_access(b.dstAccessMask), states: conv::map_buffer_access(b.srcAccessMask) .. conv::map_buffer_access(b.dstAccessMask),
target: match *b.buffer { target: b.buffer.expect("Bound buffer is needed here!"),
Buffer::Buffer(ref b) => b,
Buffer::Unbound(_) => panic!("Bound buffer is needed here!"),
},
}); });
let image_barriers = unsafe { let image_barriers = unsafe {
@ -3306,11 +3248,8 @@ pub extern "C" fn gfxCmdPipelineBarrier(
states: states:
(conv::map_image_access(b.srcAccessMask), conv::map_image_layout(b.oldLayout)) .. (conv::map_image_access(b.srcAccessMask), conv::map_image_layout(b.oldLayout)) ..
(conv::map_image_access(b.dstAccessMask), conv::map_image_layout(b.newLayout)), (conv::map_image_access(b.dstAccessMask), conv::map_image_layout(b.newLayout)),
target: match *b.image { target: b.image.expect("Bound image is needed here!"),
Image::Image(ref i) => i, range: b.image.map_subresource_range(b.subresourceRange),
Image::Unbound(_) => panic!("Bound image is needed here!"),
},
range: conv::map_subresource_range(b.subresourceRange),
}); });
commandBuffer.pipeline_barrier( commandBuffer.pipeline_barrier(
@ -3590,7 +3529,11 @@ pub extern "C" fn gfxCreateSwapchainKHR(
let images = match backbuffers { let images = match backbuffers {
hal::Backbuffer::Images(images) => images hal::Backbuffer::Images(images) => images
.into_iter() .into_iter()
.map(|image| Handle::new(Image::Image(image))) .map(|image| Handle::new(Image::Image {
raw: image,
mip_levels: 1,
array_layers: 1,
}))
.collect(), .collect(),
hal::Backbuffer::Framebuffer(_) => panic!( hal::Backbuffer::Framebuffer(_) => panic!(
"Expected backbuffer images. Backends returning only framebuffers are not supported!" "Expected backbuffer images. Backends returning only framebuffers are not supported!"

View file

@ -79,8 +79,64 @@ pub enum Pipeline<B: hal::Backend> {
} }
pub enum Image<B: hal::Backend> { pub enum Image<B: hal::Backend> {
Image(B::Image), Image { raw: B::Image, mip_levels: u32, array_layers: u32 },
Unbound(B::UnboundImage), Unbound { raw: B::UnboundImage, mip_levels: u32, array_layers: u32 },
}
impl<B: hal::Backend> Image<B> {
fn expect(&self, msg: &str) -> &B::Image {
match *self {
Image::Image { ref raw, .. } => raw,
Image::Unbound { .. } => expect_failed(msg),
}
}
fn mip_levels(&self) -> u32 {
match *self {
Image::Image { mip_levels, .. } => mip_levels,
Image::Unbound { mip_levels, .. } => mip_levels,
}
}
fn array_layers(&self) -> u32 {
match *self {
Image::Image { array_layers, .. } => array_layers,
Image::Unbound { array_layers, .. } => array_layers,
}
}
fn map_subresource_layers(&self, subresource: VkImageSubresourceLayers) -> hal::image::SubresourceLayers {
let layer_end = if subresource.layerCount == VK_REMAINING_ARRAY_LAYERS as _ {
self.array_layers()
} else {
subresource.baseArrayLayer + subresource.layerCount
};
hal::image::SubresourceLayers {
aspects: conv::map_aspect(subresource.aspectMask),
level: subresource.mipLevel as _,
layers: subresource.baseArrayLayer as _ .. layer_end as _,
}
}
fn map_subresource_range(&self,
subresource: VkImageSubresourceRange,
) -> hal::image::SubresourceRange {
let level_end = if subresource.levelCount == VK_REMAINING_MIP_LEVELS as _ {
self.mip_levels()
} else {
subresource.baseMipLevel + subresource.levelCount
};
let layer_end = if subresource.layerCount == VK_REMAINING_ARRAY_LAYERS as _ {
self.array_layers()
} else {
subresource.baseArrayLayer + subresource.layerCount
};
hal::image::SubresourceRange {
aspects: conv::map_aspect(subresource.aspectMask),
levels: subresource.baseMipLevel as _ .. level_end as _,
layers: subresource.baseArrayLayer as _ .. layer_end as _,
}
}
} }
pub enum Buffer<B: hal::Backend> { pub enum Buffer<B: hal::Backend> {
@ -88,6 +144,21 @@ pub enum Buffer<B: hal::Backend> {
Unbound(B::UnboundBuffer), Unbound(B::UnboundBuffer),
} }
impl<B: hal::Backend> Buffer<B> {
fn expect(&self, msg: &str) -> &B::Buffer {
match *self {
Buffer::Buffer(ref buf) => buf,
Buffer::Unbound(_) => expect_failed(msg),
}
}
}
#[inline(never)]
#[cold]
fn expect_failed(msg: &str) -> ! {
panic!("{}", msg)
}
pub struct CommandPool<B: hal::Backend> { pub struct CommandPool<B: hal::Backend> {
pool: B::CommandPool, pool: B::CommandPool,
buffers: Vec<VkCommandBuffer>, buffers: Vec<VkCommandBuffer>,