mirror of
https://github.com/italicsjenga/portability.git
synced 2024-11-29 18:31:31 +11:00
Robust descriptor release, safe handle access, more iterator usage
This commit is contained in:
parent
be62c9ea71
commit
2aec56a099
2
Makefile
2
Makefile
|
@ -74,7 +74,7 @@ dota-release: version-release $(DOTA_EXE)
|
||||||
dota-molten:
|
dota-molten:
|
||||||
DYLD_LIBRARY_PATH=$(CURDIR)/../MoltenVK/Package/Release/MoltenVK/macOS:$(CURDIR)/$(DOTA_DIR) $(DOTA_EXE)
|
DYLD_LIBRARY_PATH=$(CURDIR)/../MoltenVK/Package/Release/MoltenVK/macOS:$(CURDIR)/$(DOTA_DIR) $(DOTA_EXE)
|
||||||
dota-orig:
|
dota-orig:
|
||||||
DYLD_LIBRARY_PATH=$(CURDIR)/$(DOTA_DIR) $(DOTA_EXE)
|
DYLD_LIBRARY_PATH=$(CURDIR)/$(DOTA_DIR) $(DOTA_EXE) $(DOTA_PARAMS)
|
||||||
|
|
||||||
binding: $(BINDING)
|
binding: $(BINDING)
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ name = "portability_gfx"
|
||||||
default = []
|
default = []
|
||||||
dispatch = []
|
dispatch = []
|
||||||
nightly = []
|
nightly = []
|
||||||
|
metal-capture = ["gfx-backend-metal/auto-capture"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lazy_static = "1.0"
|
lazy_static = "1.0"
|
||||||
|
|
|
@ -54,11 +54,7 @@ impl<T: 'static> Handle<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_ref(&self) -> Option<&T> {
|
pub fn as_ref(&self) -> Option<&T> {
|
||||||
if self.0 == VK_NULL_HANDLE as *mut T {
|
unsafe { self.0.as_ref() }
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(unsafe { &*self.0 })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +66,9 @@ impl<T> Handle<T> {
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "nightly"))]
|
#[cfg(not(feature = "nightly"))]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check(&self) {}
|
fn check(&self) {
|
||||||
|
debug_assert!(!self.0.is_null());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Clone for Handle<T> {
|
impl<T> Clone for Handle<T> {
|
||||||
|
|
|
@ -2303,19 +2303,18 @@ pub extern "C" fn gfxCreateDescriptorSetLayout(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut bindings = Vec::with_capacity(layout_bindings.len());
|
let bindings = layout_bindings
|
||||||
for binding in layout_bindings {
|
.iter()
|
||||||
bindings.push(pso::DescriptorSetLayoutBinding {
|
.map(|binding| pso::DescriptorSetLayoutBinding {
|
||||||
binding: binding.binding as _,
|
binding: binding.binding as _,
|
||||||
ty: conv::map_descriptor_type(binding.descriptorType),
|
ty: conv::map_descriptor_type(binding.descriptorType),
|
||||||
count: binding.descriptorCount as _,
|
count: binding.descriptorCount as _,
|
||||||
stage_flags: conv::map_stage_flags(binding.stageFlags),
|
stage_flags: conv::map_stage_flags(binding.stageFlags),
|
||||||
immutable_samplers: !binding.pImmutableSamplers.is_null(),
|
immutable_samplers: !binding.pImmutableSamplers.is_null(),
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
let set_layout = gpu.device
|
let set_layout = gpu.device
|
||||||
.create_descriptor_set_layout(&bindings, sampler_iter);
|
.create_descriptor_set_layout(bindings, sampler_iter);
|
||||||
|
|
||||||
unsafe { *pSetLayout = Handle::new(set_layout); }
|
unsafe { *pSetLayout = Handle::new(set_layout); }
|
||||||
VkResult::VK_SUCCESS
|
VkResult::VK_SUCCESS
|
||||||
|
@ -2350,12 +2349,11 @@ pub extern "C" fn gfxCreateDescriptorPool(
|
||||||
ty: conv::map_descriptor_type(pool.type_),
|
ty: conv::map_descriptor_type(pool.type_),
|
||||||
count: pool.descriptorCount as _,
|
count: pool.descriptorCount as _,
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let pool = super::DescriptorPool {
|
let pool = super::DescriptorPool {
|
||||||
raw: gpu.device
|
raw: gpu.device
|
||||||
.create_descriptor_pool(info.maxSets as _, &ranges),
|
.create_descriptor_pool(info.maxSets as _, ranges),
|
||||||
sets: if info.flags & VkDescriptorPoolCreateFlagBits::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT as u32 != 0 {
|
sets: if info.flags & VkDescriptorPoolCreateFlagBits::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT as u32 != 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -2415,41 +2413,40 @@ pub extern "C" fn gfxAllocateDescriptorSets(
|
||||||
let sets = unsafe {
|
let sets = unsafe {
|
||||||
slice::from_raw_parts_mut(pDescriptorSets, info.descriptorSetCount as _)
|
slice::from_raw_parts_mut(pDescriptorSets, info.descriptorSetCount as _)
|
||||||
};
|
};
|
||||||
let mut result = VkResult::VK_SUCCESS;
|
|
||||||
assert_eq!(descriptor_sets.len(), info.descriptorSetCount as usize);
|
assert_eq!(descriptor_sets.len(), info.descriptorSetCount as usize);
|
||||||
|
|
||||||
for (i, raw_set) in descriptor_sets.into_iter().enumerate() {
|
let error = descriptor_sets
|
||||||
match raw_set {
|
.iter()
|
||||||
Ok(set) => {
|
.find(|raw_set| raw_set.is_err())
|
||||||
sets[i] = Handle::new(set);
|
.map(|raw_set| match *raw_set {
|
||||||
}
|
Ok(_) => unreachable!(),
|
||||||
Err(e) => {
|
Err(e) => e,
|
||||||
// revert all the changes!
|
});
|
||||||
for set in sets[..i].iter_mut() {
|
|
||||||
let _ = set.unbox();
|
|
||||||
}
|
|
||||||
for set in sets.iter_mut() {
|
|
||||||
*set = Handle::null();
|
|
||||||
}
|
|
||||||
result = match e {
|
|
||||||
pso::AllocationError::OutOfHostMemory => VkResult::VK_ERROR_OUT_OF_HOST_MEMORY,
|
|
||||||
pso::AllocationError::OutOfDeviceMemory => VkResult::VK_ERROR_OUT_OF_DEVICE_MEMORY,
|
|
||||||
pso::AllocationError::OutOfPoolMemory => VkResult::VK_ERROR_OUT_OF_POOL_MEMORY_KHR,
|
|
||||||
pso::AllocationError::IncompatibleLayout => VkResult::VK_ERROR_DEVICE_LOST,
|
|
||||||
pso::AllocationError::FragmentedPool => VkResult::VK_ERROR_FRAGMENTED_POOL,
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if result == VkResult::VK_SUCCESS {
|
match error {
|
||||||
if let Some(ref mut local_sets) = pool.sets {
|
Some(e) => {
|
||||||
local_sets.extend_from_slice(sets);
|
pool.raw.free_sets(descriptor_sets.into_iter().filter_map(|ds| ds.ok()));
|
||||||
|
for set in sets.iter_mut() {
|
||||||
|
*set = Handle::null();
|
||||||
|
}
|
||||||
|
match e {
|
||||||
|
pso::AllocationError::OutOfHostMemory => VkResult::VK_ERROR_OUT_OF_HOST_MEMORY,
|
||||||
|
pso::AllocationError::OutOfDeviceMemory => VkResult::VK_ERROR_OUT_OF_DEVICE_MEMORY,
|
||||||
|
pso::AllocationError::OutOfPoolMemory => VkResult::VK_ERROR_OUT_OF_POOL_MEMORY_KHR,
|
||||||
|
pso::AllocationError::IncompatibleLayout => VkResult::VK_ERROR_DEVICE_LOST,
|
||||||
|
pso::AllocationError::FragmentedPool => VkResult::VK_ERROR_FRAGMENTED_POOL,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
for (set, raw_set) in sets.iter_mut().zip(descriptor_sets) {
|
||||||
|
*set = Handle::new(raw_set.unwrap());
|
||||||
|
}
|
||||||
|
if let Some(ref mut local_sets) = pool.sets {
|
||||||
|
local_sets.extend_from_slice(sets);
|
||||||
|
}
|
||||||
|
VkResult::VK_SUCCESS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxFreeDescriptorSets(
|
pub extern "C" fn gfxFreeDescriptorSets(
|
||||||
|
@ -2643,10 +2640,10 @@ pub extern "C" fn gfxCreateRenderPass(
|
||||||
let info = unsafe { &*pCreateInfo };
|
let info = unsafe { &*pCreateInfo };
|
||||||
|
|
||||||
// Attachment descriptions
|
// Attachment descriptions
|
||||||
let attachments = unsafe {
|
let raw_attachments = unsafe {
|
||||||
slice::from_raw_parts(info.pAttachments, info.attachmentCount as _)
|
slice::from_raw_parts(info.pAttachments, info.attachmentCount as _)
|
||||||
};
|
};
|
||||||
let attachments = attachments
|
let attachments = raw_attachments
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|attachment| {
|
.map(|attachment| {
|
||||||
assert_eq!(attachment.flags, 0); // TODO
|
assert_eq!(attachment.flags, 0); // TODO
|
||||||
|
@ -2667,16 +2664,15 @@ pub extern "C" fn gfxCreateRenderPass(
|
||||||
},
|
},
|
||||||
layouts: initial_layout .. final_layout,
|
layouts: initial_layout .. final_layout,
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Subpass descriptions
|
// Subpass descriptions
|
||||||
let subpasses = unsafe {
|
let subpasses_raw = unsafe {
|
||||||
slice::from_raw_parts(info.pSubpasses, info.subpassCount as _)
|
slice::from_raw_parts(info.pSubpasses, info.subpassCount as _)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Store all attachment references, referenced by the subpasses.
|
// Store all attachment references, referenced by the subpasses.
|
||||||
let mut attachment_refs = Vec::with_capacity(subpasses.len());
|
let mut attachment_refs = Vec::with_capacity(subpasses_raw.len());
|
||||||
struct AttachmentRefs {
|
struct AttachmentRefs {
|
||||||
input: Vec<pass::AttachmentRef>,
|
input: Vec<pass::AttachmentRef>,
|
||||||
color: Vec<pass::AttachmentRef>,
|
color: Vec<pass::AttachmentRef>,
|
||||||
|
@ -2689,7 +2685,7 @@ pub extern "C" fn gfxCreateRenderPass(
|
||||||
(att_ref.attachment as _, conv::map_image_layout(att_ref.layout))
|
(att_ref.attachment as _, conv::map_image_layout(att_ref.layout))
|
||||||
}
|
}
|
||||||
|
|
||||||
for subpass in subpasses {
|
for subpass in subpasses_raw {
|
||||||
let input = unsafe {
|
let input = unsafe {
|
||||||
slice::from_raw_parts(subpass.pInputAttachments, subpass.inputAttachmentCount as _)
|
slice::from_raw_parts(subpass.pInputAttachments, subpass.inputAttachmentCount as _)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -2743,8 +2739,7 @@ pub extern "C" fn gfxCreateRenderPass(
|
||||||
inputs: &attachment_ref.input,
|
inputs: &attachment_ref.input,
|
||||||
resolves: &attachment_ref.resolve,
|
resolves: &attachment_ref.resolve,
|
||||||
preserves: &attachment_ref.preserve,
|
preserves: &attachment_ref.preserve,
|
||||||
})
|
});
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Subpass dependencies
|
// Subpass dependencies
|
||||||
let dependencies = unsafe {
|
let dependencies = unsafe {
|
||||||
|
@ -2780,12 +2775,11 @@ pub extern "C" fn gfxCreateRenderPass(
|
||||||
stages: src_stage .. dst_stage,
|
stages: src_stage .. dst_stage,
|
||||||
accesses: src_access .. dst_access,
|
accesses: src_access .. dst_access,
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let render_pass = gpu
|
let render_pass = gpu
|
||||||
.device
|
.device
|
||||||
.create_render_pass(&attachments, &subpasses, &dependencies);
|
.create_render_pass(attachments, subpasses, dependencies);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
*pRenderPass = Handle::new(render_pass);
|
*pRenderPass = Handle::new(render_pass);
|
||||||
|
|
Loading…
Reference in a new issue