Skip to content

Commit 173eb0f

Browse files
bors[bot]kvark
andcommitted
Merge #109
109: [WIP] Handle sanitation and gfx-hal update r=msiglreith,grovesNL a=kvark Depends on gfx-rs/gfx#2195 Depends on gfx-rs/metal-rs#59 Fixes #103 Co-authored-by: Dzmitry Malyshau <[email protected]>
2 parents 468147d + 2cf691a commit 173eb0f

File tree

8 files changed

+107
-108
lines changed

8 files changed

+107
-108
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ conformance/*.qpa
55
conformance/*.txt
66
**/*.rs.bk
77
.vscode/
8+
.lldbinit

.lldbinit

-1
This file was deleted.

Cargo.lock

+34-72
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Makefile

+11-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ DEQP_DIR=$(CTS_DIR)/build/external/vulkancts/modules/vulkan/
1212
DEQP=cd $(DEQP_DIR) && RUST_LOG=debug LD_LIBRARY_PATH=$(FULL_LIBRARY_PATH) ./deqp-vk
1313
DOTA_DIR=../dota2/bin/osx64
1414
DOTA_EXE=$(DOTA_DIR)/dota2.app/Contents/MacOS/dota2
15-
DOTA_PARAMS=-vulkan_disable_occlusion_queries -vulkan_scene_system_job_cost 2
15+
#DOTA_PARAMS=-vulkan_disable_occlusion_queries -vulkan_scene_system_job_cost 2
16+
DOTA_PARAMS=-vulkan_disable_occlusion_queries
1617

1718
RUST_BACKTRACE:=1
1819
BACKEND:=gl
@@ -46,7 +47,7 @@ FULL_LIBRARY_PATH=$(CURDIR)/target/debug
4647
LIBRARY=target/debug/libportability.$(LIB_EXTENSION)
4748
LIBRARY_FAST=target/release/libportability.$(LIB_EXTENSION)
4849

49-
.PHONY: all rebuild debug release version-debug version-release binding run cts clean cherry dota-debug dota-release
50+
.PHONY: all rebuild debug release version-debug version-release binding run cts clean cherry dota-debug dota-release dota-orig
5051

5152
all: $(TARGET)
5253

@@ -65,10 +66,15 @@ version-release:
6566
cargo rustc --release --manifest-path libportability/Cargo.toml --features $(BACKEND) -- -Clink-arg="-current_version 1.0.0" -Clink-arg="-compatibility_version 1.0.0"
6667

6768
dota-debug: version-debug $(DOTA_EXE)
68-
DYLD_LIBRARY_PATH=`pwd`/target/debug:`pwd`/$(DOTA_DIR) $(DOTA_EXE) $(DOTA_PARAMS)
69+
echo "env DYLD_LIBRARY_PATH=$(CURDIR)/target/debug:$(CURDIR)/$(DOTA_DIR)" >.lldbinit
70+
DYLD_LIBRARY_PATH=$(CURDIR)/target/debug:$(CURDIR)/$(DOTA_DIR) $(DEBUGGER) $(DOTA_EXE) $(DOTA_PARAMS)
6971

7072
dota-release: version-release $(DOTA_EXE)
71-
DYLD_LIBRARY_PATH=`pwd`/target/release:`pwd`/$(DOTA_DIR) $(DOTA_EXE) $(DOTA_PARAMS)
73+
DYLD_LIBRARY_PATH=$(CURDIR)/target/release:$(CURDIR)/$(DOTA_DIR) $(DOTA_EXE) $(DOTA_PARAMS)
74+
dota-molten:
75+
DYLD_LIBRARY_PATH=$(CURDIR)/../MoltenVK/Package/Release/MoltenVK/macOS:$(CURDIR)/$(DOTA_DIR) $(DOTA_EXE)
76+
dota-orig:
77+
DYLD_LIBRARY_PATH=$(CURDIR)/$(DOTA_DIR) $(DOTA_EXE)
7278

7379
binding: $(BINDING)
7480

@@ -103,6 +109,7 @@ cts:
103109
else
104110
ifdef debug
105111
cts: $(LIBRARY)
112+
echo "env LD_LIBRARY_PATH=$(FULL_LIBRARY_PATH)" >.lldbinit
106113
#(cd $(DEQP_DIR) && LD_LIBRARY_PATH=$(FULL_LIBRARY_PATH) $(DEBUGGER) ./deqp-vk -n $(debug))
107114
LD_LIBRARY_PATH=$(FULL_LIBRARY_PATH) $(DEBUGGER) $(DEQP_DIR)/deqp-vk -n $(debug)
108115
else

libportability-gfx/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ nightly = []
1818
[dependencies]
1919
lazy_static = "1.0"
2020
log = "0.4"
21+
smallvec = "0.6"
2122

2223
[dependencies.env_logger]
2324
version = "0.5"

libportability-gfx/src/handle.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use VK_NULL_HANDLE;
22
use std::{borrow, cmp, fmt, ops};
33
#[cfg(feature = "nightly")]
4-
use std::collections::HashMap;
5-
#[cfg(feature = "nightly")]
64
use std::sync::{Arc, Mutex};
75

6+
#[cfg(feature = "nightly")]
7+
use hal::backend::FastHashMap;
8+
89
#[cfg(feature = "nightly")]
910
lazy_static! {
10-
static ref REGISTRY: Arc<Mutex<HashMap<usize, &'static str>>> = Arc::new(Mutex::new(HashMap::new()));
11+
static ref REGISTRY: Arc<Mutex<FastHashMap<usize, &'static str>>> = Arc::new(Mutex::new(FastHashMap::default()));
1112
}
1213

1314
#[repr(C)]
@@ -61,6 +62,17 @@ impl<T: 'static> Handle<T> {
6162
}
6263
}
6364

65+
impl<T> Handle<T> {
66+
#[cfg(feature = "nightly")]
67+
#[inline]
68+
fn check(&self) {
69+
assert!(REGISTRY.lock().unwrap().contains_key(&(self.0 as _)));
70+
}
71+
#[cfg(not(feature = "nightly"))]
72+
#[inline]
73+
fn check(&self) {}
74+
}
75+
6476
impl<T> Clone for Handle<T> {
6577
fn clone(&self) -> Self {
6678
Handle(self.0)
@@ -72,18 +84,21 @@ impl<T> Copy for Handle<T> {}
7284
impl<T> ops::Deref for Handle<T> {
7385
type Target = T;
7486
fn deref(&self) -> &T {
87+
self.check();
7588
unsafe { &*self.0 }
7689
}
7790
}
7891

7992
impl<T> ops::DerefMut for Handle<T> {
8093
fn deref_mut(&mut self) -> &mut T {
94+
self.check();
8195
unsafe { &mut *self.0 }
8296
}
8397
}
8498

8599
impl<T> borrow::Borrow<T> for Handle<T> {
86100
fn borrow(&self) -> &T {
101+
self.check();
87102
unsafe { &*self.0 }
88103
}
89104
}

libportability-gfx/src/impls.rs

+41-28
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use hal::device::WaitFor;
99
use hal::pool::RawCommandPool;
1010
use hal::queue::RawCommandQueue;
1111

12+
use smallvec::SmallVec;
13+
1214
use std::ffi::{CStr, CString};
1315
#[cfg(feature = "renderdoc")]
1416
use std::os::raw::c_void;
@@ -357,7 +359,7 @@ pub extern "C" fn gfxGetPhysicalDeviceMemoryProperties(
357359
}
358360
#[inline]
359361
pub extern "C" fn gfxGetInstanceProcAddr(
360-
instance: VkInstance,
362+
_instance: VkInstance,
361363
pName: *const ::std::os::raw::c_char,
362364
) -> PFN_vkVoidFunction {
363365
let name = unsafe { CStr::from_ptr(pName) };
@@ -1105,9 +1107,7 @@ pub extern "C" fn gfxBindBufferMemory(
11051107
memory: VkDeviceMemory,
11061108
memoryOffset: VkDeviceSize,
11071109
) -> VkResult {
1108-
let temp = unsafe { mem::zeroed() };
1109-
1110-
*buffer = match mem::replace(&mut *buffer, temp) {
1110+
let new = match mem::replace(&mut *buffer, unsafe { mem::zeroed() }) {
11111111
Buffer::Buffer(_) => panic!("A non-sparse buffer can only be bound once!"),
11121112
Buffer::Unbound(unbound) => {
11131113
Buffer::Buffer(
@@ -1118,6 +1118,11 @@ pub extern "C" fn gfxBindBufferMemory(
11181118
}
11191119
};
11201120

1121+
// We need to move the value out of the Handle here,
1122+
// and then put something else back in.
1123+
let temp = mem::replace(&mut *buffer, new);
1124+
mem::forget(temp);
1125+
11211126
VkResult::VK_SUCCESS
11221127
}
11231128
#[inline]
@@ -1127,9 +1132,7 @@ pub extern "C" fn gfxBindImageMemory(
11271132
memory: VkDeviceMemory,
11281133
memoryOffset: VkDeviceSize,
11291134
) -> VkResult {
1130-
let temp = unsafe { mem::zeroed() };
1131-
1132-
*image = match mem::replace(&mut *image, temp) {
1135+
let new = match mem::replace(&mut *image, unsafe { mem::zeroed() }) {
11331136
Image::Image { .. } => panic!("An non-sparse image can only be bound once!"),
11341137
Image::Unbound { raw, mip_levels, array_layers } => {
11351138
Image::Image {
@@ -1140,6 +1143,11 @@ pub extern "C" fn gfxBindImageMemory(
11401143
}
11411144
};
11421145

1146+
// We need to move the value out of the Handle here,
1147+
// and then put something else back in.
1148+
let temp = mem::replace(&mut *image, new);
1149+
mem::forget(temp);
1150+
11431151
VkResult::VK_SUCCESS
11441152
}
11451153
#[inline]
@@ -1719,7 +1727,13 @@ pub extern "C" fn gfxCreateGraphicsPipelines(
17191727
};
17201728

17211729
let shaders = {
1722-
let mut set: pso::GraphicsShaderSet<_> = unsafe { mem::zeroed() };
1730+
let mut set = pso::GraphicsShaderSet {
1731+
vertex: unsafe { mem::zeroed() }, // fake entry point
1732+
hull: None,
1733+
domain: None,
1734+
geometry: None,
1735+
fragment: None,
1736+
};
17231737

17241738
let stages = unsafe {
17251739
slice::from_raw_parts(info.pStages, info.stageCount as _)
@@ -1738,7 +1752,10 @@ pub extern "C" fn gfxCreateGraphicsPipelines(
17381752
};
17391753

17401754
match stage.stage {
1741-
VK_SHADER_STAGE_VERTEX_BIT => { set.vertex = entry_point; }
1755+
VK_SHADER_STAGE_VERTEX_BIT => {
1756+
let fake_vs_entry = mem::replace(&mut set.vertex, entry_point);
1757+
mem::forget(fake_vs_entry);
1758+
}
17421759
VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT => { set.hull = Some(entry_point); }
17431760
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT => { set.domain = Some(entry_point); }
17441761
VK_SHADER_STAGE_GEOMETRY_BIT => { set.geometry = Some(entry_point); }
@@ -2431,10 +2448,9 @@ pub extern "C" fn gfxFreeDescriptorSets(
24312448
assert!(descriptorPool.sets.is_none());
24322449

24332450
descriptorPool.raw.free_sets(
2434-
&descriptor_sets
2451+
descriptor_sets
24352452
.into_iter()
24362453
.filter_map(|set| set.unbox())
2437-
.collect::<Vec<_>>()
24382454
);
24392455

24402456
VkResult::VK_SUCCESS
@@ -2450,7 +2466,8 @@ pub extern "C" fn gfxUpdateDescriptorSets(
24502466
let write_infos = unsafe {
24512467
slice::from_raw_parts(pDescriptorWrites, descriptorWriteCount as _)
24522468
};
2453-
let mut writes = Vec::new(); //TODO: avoid allocation here and below
2469+
//TODO: investigate the safety of passing one giant iterator here
2470+
let mut writes = SmallVec::<[pso::DescriptorSetWrite<_, _>; 16]>::with_capacity(write_infos.len());
24542471

24552472
for write in write_infos {
24562473
let image_info = unsafe {
@@ -2464,14 +2481,12 @@ pub extern "C" fn gfxUpdateDescriptorSets(
24642481
};
24652482

24662483
let ty = conv::map_descriptor_type(write.descriptorType);
2467-
let descriptors = match ty {
2484+
let descriptors: SmallVec<[_; 4]> = match ty {
24682485
pso::DescriptorType::Sampler => {
24692486
image_info
24702487
.into_iter()
2471-
.map(|image| pso::Descriptor::Sampler(
2472-
&*image.sampler,
2473-
))
2474-
.collect::<Vec<_>>()
2488+
.map(|image| pso::Descriptor::Sampler(&*image.sampler))
2489+
.collect()
24752490
}
24762491
pso::DescriptorType::InputAttachment |
24772492
pso::DescriptorType::SampledImage |
@@ -2482,23 +2497,23 @@ pub extern "C" fn gfxUpdateDescriptorSets(
24822497
&*image.imageView,
24832498
conv::map_image_layout(image.imageLayout),
24842499
))
2485-
.collect::<Vec<_>>()
2500+
.collect()
24862501
}
24872502
pso::DescriptorType::UniformTexelBuffer => {
24882503
texel_buffer_views
24892504
.into_iter()
24902505
.map(|view| pso::Descriptor::UniformTexelBuffer(
24912506
&**view,
24922507
))
2493-
.collect::<Vec<_>>()
2508+
.collect()
24942509
}
24952510
pso::DescriptorType::StorageTexelBuffer => {
24962511
texel_buffer_views
24972512
.into_iter()
24982513
.map(|view| pso::Descriptor::StorageTexelBuffer(
24992514
&**view,
25002515
))
2501-
.collect::<Vec<_>>()
2516+
.collect()
25022517
}
25032518
pso::DescriptorType::UniformBuffer |
25042519
pso::DescriptorType::StorageBuffer |
@@ -2518,7 +2533,7 @@ pub extern "C" fn gfxUpdateDescriptorSets(
25182533
Some(buffer.offset) .. end,
25192534
)
25202535
})
2521-
.collect::<Vec<_>>()
2536+
.collect()
25222537
}
25232538
pso::DescriptorType::CombinedImageSampler => {
25242539
image_info
@@ -2528,7 +2543,7 @@ pub extern "C" fn gfxUpdateDescriptorSets(
25282543
conv::map_image_layout(image.imageLayout),
25292544
&*image.sampler,
25302545
))
2531-
.collect::<Vec<_>>()
2546+
.collect()
25322547
}
25332548
};
25342549

@@ -3096,15 +3111,13 @@ pub extern "C" fn gfxCmdBindVertexBuffers(
30963111

30973112
let views = buffers
30983113
.into_iter()
3099-
.zip(offsets.into_iter())
3114+
.zip(offsets)
31003115
.map(|(buffer, offset)| {
31013116
let buffer = buffer.expect("Non-sparse buffers need to be bound to device memory.");
3117+
(buffer, *offset)
3118+
});
31023119

3103-
(buffer, *offset as _)
3104-
})
3105-
.collect();
3106-
3107-
commandBuffer.bind_vertex_buffers(firstBinding, pso::VertexBufferSet(views));
3120+
commandBuffer.bind_vertex_buffers(firstBinding, views);
31083121
}
31093122
#[inline]
31103123
pub extern "C" fn gfxCmdDraw(

libportability-gfx/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ extern crate gfx_backend_vulkan as back;
1818
extern crate lazy_static;
1919
#[macro_use]
2020
extern crate log;
21+
extern crate smallvec;
2122
#[cfg(feature = "env_logger")]
2223
extern crate env_logger;
2324
#[cfg(feature = "renderdoc")]

0 commit comments

Comments
 (0)