Fix the difference in clear attachment data with gfx

This commit is contained in:
Dzmitry Malyshau 2020-08-22 01:22:48 -04:00 committed by Dzmitry Malyshau
parent 7034f366b3
commit 47bbd375b3
2 changed files with 40 additions and 14 deletions

View file

@ -2344,7 +2344,7 @@ pub unsafe extern "C" fn gfxCreateGraphicsPipelines(
let layout = &*info.layout; let layout = &*info.layout;
let subpass = pass::Subpass { let subpass = pass::Subpass {
index: info.subpass as _, index: info.subpass as _,
main_pass: &*info.renderPass, main_pass: &info.renderPass.raw,
}; };
let flags = { let flags = {
@ -2976,7 +2976,7 @@ pub unsafe extern "C" fn gfxCreateFramebuffer(
.map(|attachment| attachment.as_native().unwrap()); .map(|attachment| attachment.as_native().unwrap());
Framebuffer::Native( Framebuffer::Native(
gpu.device gpu.device
.create_framebuffer(&*info.renderPass, attachments, extent) .create_framebuffer(&info.renderPass.raw, attachments, extent)
.unwrap(), .unwrap(),
) )
}; };
@ -3008,7 +3008,7 @@ pub unsafe extern "C" fn gfxCreateRenderPass(
// Attachment descriptions // Attachment descriptions
let raw_attachments = slice::from_raw_parts(info.pAttachments, info.attachmentCount as _); let raw_attachments = slice::from_raw_parts(info.pAttachments, info.attachmentCount as _);
let attachments = raw_attachments.into_iter().map(|attachment| { let attachments = raw_attachments.iter().map(|attachment| {
assert_eq!(attachment.flags, 0); // TODO assert_eq!(attachment.flags, 0); // TODO
let initial_layout = conv::map_image_layout(attachment.initialLayout); let initial_layout = conv::map_image_layout(attachment.initialLayout);
@ -3137,11 +3137,24 @@ pub unsafe extern "C" fn gfxCreateRenderPass(
} }
}); });
let clear_attachment_mask = attachments
.clone()
.enumerate()
.filter(|(_, at)| {
at.ops.load == hal::pass::AttachmentLoadOp::Clear
|| (at.format.map_or(false, |f| f.is_stencil())
&& at.stencil_ops.load == hal::pass::AttachmentLoadOp::Clear)
})
.fold(0u64, |mask, (i, _)| mask | (1 << i));
let render_pass = match gpu let render_pass = match gpu
.device .device
.create_render_pass(attachments, subpasses, dependencies) .create_render_pass(attachments, subpasses, dependencies)
{ {
Ok(raw) => raw, Ok(raw) => RenderPass {
raw,
clear_attachment_mask,
},
Err(oom) => return map_oom(oom), Err(oom) => return map_oom(oom),
}; };
@ -3156,7 +3169,7 @@ pub unsafe extern "C" fn gfxDestroyRenderPass(
_pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
if let Some(rp) = renderPass.unbox() { if let Some(rp) = renderPass.unbox() {
gpu.device.destroy_render_pass(rp); gpu.device.destroy_render_pass(rp.raw);
} }
} }
#[inline] #[inline]
@ -3279,7 +3292,7 @@ pub unsafe extern "C" fn gfxBeginCommandBuffer(
let inheritance = match info.pInheritanceInfo.as_ref() { let inheritance = match info.pInheritanceInfo.as_ref() {
Some(ii) => com::CommandBufferInheritanceInfo { Some(ii) => com::CommandBufferInheritanceInfo {
subpass: ii.renderPass.as_ref().map(|rp| pass::Subpass { subpass: ii.renderPass.as_ref().map(|rp| pass::Subpass {
main_pass: &*rp, main_pass: &rp.raw,
index: ii.subpass as _, index: ii.subpass as _,
}), }),
framebuffer: ii framebuffer: ii
@ -4075,17 +4088,25 @@ pub unsafe extern "C" fn gfxCmdBeginRenderPass(
w: info.renderArea.extent.width as _, w: info.renderArea.extent.width as _,
h: info.renderArea.extent.height as _, h: info.renderArea.extent.height as _,
}; };
// gfx-hal expects exactly one clear value for an attachment that needs
// to be cleared, while Vulkan has gaps.
let clear_values = slice::from_raw_parts(info.pClearValues, info.clearValueCount as _) let clear_values = slice::from_raw_parts(info.pClearValues, info.clearValueCount as _)
.into_iter() .iter()
.map(|cv| { .enumerate()
// HAL and Vulkan clear value union sharing same memory representation .filter_map(|(i, cv)| {
mem::transmute::<_, com::ClearValue>(*cv) if info.renderPass.clear_attachment_mask & (1 << i) != 0 {
}); // HAL and Vulkan clear value union sharing same memory representation
Some(mem::transmute::<_, com::ClearValue>(*cv))
} else {
None
}
})
.collect::<Vec<_>>();
let contents = conv::map_subpass_contents(contents); let contents = conv::map_subpass_contents(contents);
let framebuffer = info.framebuffer.resolve(info.renderPass); let framebuffer = info.framebuffer.resolve(info.renderPass);
commandBuffer.begin_render_pass( commandBuffer.begin_render_pass(
&*info.renderPass, &info.renderPass.raw,
framebuffer, framebuffer,
render_area, render_area,
clear_values, clear_values,

View file

@ -68,7 +68,7 @@ pub type VkBuffer = Handle<<B as hal::Backend>::Buffer>;
pub type VkSemaphore = Handle<Semaphore<B>>; pub type VkSemaphore = Handle<Semaphore<B>>;
pub type VkEvent = Handle<<B as hal::Backend>::Event>; pub type VkEvent = Handle<<B as hal::Backend>::Event>;
pub type VkFence = Handle<Fence<B>>; pub type VkFence = Handle<Fence<B>>;
pub type VkRenderPass = Handle<<B as hal::Backend>::RenderPass>; pub type VkRenderPass = Handle<RenderPass<B>>;
pub type VkFramebuffer = Handle<Framebuffer>; pub type VkFramebuffer = Handle<Framebuffer>;
pub type VkPipeline = Handle<Pipeline<B>>; pub type VkPipeline = Handle<Pipeline<B>>;
pub type VkPipelineCache = Handle<<B as hal::Backend>::PipelineCache>; pub type VkPipelineCache = Handle<<B as hal::Backend>::PipelineCache>;
@ -98,6 +98,11 @@ pub struct DescriptorPool<B: hal::Backend> {
set_handles: Option<Vec<VkDescriptorSet>>, set_handles: Option<Vec<VkDescriptorSet>>,
} }
pub struct RenderPass<B: hal::Backend> {
raw: B::RenderPass,
clear_attachment_mask: u64,
}
pub enum Pipeline<B: hal::Backend> { pub enum Pipeline<B: hal::Backend> {
Graphics(B::GraphicsPipeline), Graphics(B::GraphicsPipeline),
Compute(B::ComputePipeline), Compute(B::ComputePipeline),
@ -187,7 +192,7 @@ impl Framebuffer {
sc.lazy_framebuffers.push(unsafe { sc.lazy_framebuffers.push(unsafe {
use hal::device::Device; use hal::device::Device;
gpu.device gpu.device
.create_framebuffer(&*render_pass, attachments, extent) .create_framebuffer(&render_pass.raw, attachments, extent)
.unwrap() .unwrap()
}); });
sc.lazy_framebuffers.last().unwrap() sc.lazy_framebuffers.last().unwrap()