Skip to content

Commit

Permalink
[metal] resource count enforcement, travis update
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Oct 16, 2017
1 parent 0e647a0 commit 54e072f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 21 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ rust:
os:
- linux
- osx
osx_image: xcode8
branches:
except:
- staging.tmp
Expand All @@ -33,7 +34,7 @@ before_install:
# (assuming it will have libsdl2-dev and Rust by then)
# see https://docs.travis-ci.com/user/trusty-ci-environment/
- if [[ $TRAVIS_OS_NAME == "linux" ]]; then export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start && make travis-sdl2; fi
- if [[ $TRAVIS_OS_NAME == osx ]]; then brew update && brew install sdl2 && brew upgrade cmake; fi
- if [[ $TRAVIS_OS_NAME == osx ]]; then brew update && brew install sdl2 && brew install gcc5 && brew upgrade cmake; fi

addons:
apt:
Expand Down
2 changes: 2 additions & 0 deletions bors.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ status = [
"continuous-integration/travis-ci/push",
"continuous-integration/appveyor/branch"
]

timeout_sec = 14400 # 6 hours
57 changes: 37 additions & 20 deletions src/backend/metal/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ impl Drop for Adapter {
struct PrivateCapabilities {
resource_heaps: bool,
argument_buffers: bool,
max_buffers_per_stage: usize,
max_textures_per_stage: usize,
max_samplers_per_stage: usize,
}

pub struct Device {
Expand Down Expand Up @@ -116,12 +119,16 @@ impl core::Adapter<Backend> for Adapter {
.push(unsafe { core::CommandQueue::new(command::CommandQueue::new(self.device)) }),
}
}

assert!(queue_descs.len() == 1, "Metal only supports one queue family");

let is_mac = self.device.supports_feature_set(MTLFeatureSet::macOS_GPUFamily1_v1);

let private_caps = PrivateCapabilities {
resource_heaps: self.supports_any(RESOURCE_HEAP_SUPPORT),
argument_buffers: self.supports_any(ARGUMENT_BUFFER_SUPPORT) && false, //TODO
max_buffers_per_stage: 31,
max_textures_per_stage: if is_mac {128} else {31},
max_samplers_per_stage: 31,
};

unsafe { self.device.retain(); }
Expand All @@ -133,7 +140,7 @@ impl core::Adapter<Backend> for Adapter {
max_patch_size: 0, // No tesselation
max_viewports: 1,

min_buffer_copy_offset_alignment: 4, // TODO: Lower on iOS
min_buffer_copy_offset_alignment: if is_mac {256} else {64},
min_buffer_copy_pitch_alignment: 4, // TODO: made this up
min_uniform_buffer_offset_alignment: 1, // TODO

Expand Down Expand Up @@ -501,9 +508,9 @@ impl core::Device<Backend> for Device {
use core::pso::{STAGE_VERTEX, STAGE_FRAGMENT};

struct Counters {
buffers: u32,
textures: u32,
samplers: u32,
buffers: usize,
textures: usize,
samplers: usize,
}
let mut stage_infos = [
(STAGE_VERTEX, spirv::ExecutionModel::Vertex, Counters { buffers:0, textures:0, samplers:0 }),
Expand All @@ -526,15 +533,14 @@ impl core::Device<Backend> for Device {
DescriptorType::Sampler => &mut counters.samplers,
_ => unimplemented!()
};
let count_base = *count;
for i in 0 .. set_binding.count {
let location = msl::ResourceBindingLocation {
stage,
desc_set: set_index as _,
binding: (set_binding.binding + i) as _,
};
let res_binding = msl::ResourceBinding {
resource_id: *count,
resource_id: *count as _,
force_used: false,
};
*count += 1;
Expand All @@ -554,7 +560,7 @@ impl core::Device<Backend> for Device {
binding: 0,
};
let res_binding = msl::ResourceBinding {
resource_id: counters.buffers,
resource_id: counters.buffers as _,
force_used: false,
};
res_overrides.insert(location, res_binding);
Expand All @@ -564,6 +570,13 @@ impl core::Device<Backend> for Device {
}
}

// TODO: return an `Err` when HAL signature of the function supports it
for &(_, _, ref counters) in &stage_infos {
assert!(counters.buffers <= self.private_caps.max_buffers_per_stage);
assert!(counters.textures <= self.private_caps.max_textures_per_stage);
assert!(counters.samplers <= self.private_caps.max_samplers_per_stage);
}

n::PipelineLayout { res_overrides }
}

Expand Down Expand Up @@ -892,19 +905,23 @@ impl core::Device<Backend> for Device {
}

fn get_buffer_requirements(&mut self, buffer: &n::UnboundBuffer) -> memory::Requirements {
// We don't know what memory type the user will try to allocate the buffer with, so we test them
// all get the most stringent ones. Note we don't check Shared because heaps can't use it
let mut max_size = 0;
let mut max_alignment = 0;
for &options in [
MTLResourceStorageModeManaged,
MTLResourceStorageModeManaged | MTLResourceCPUCacheModeWriteCombined,
MTLResourceStorageModePrivate,
].iter() {
let requirements = self.device.heap_buffer_size_and_align(buffer.size, options);
max_size = cmp::max(max_size, requirements.size);
max_alignment = cmp::max(max_alignment, requirements.align);
let mut max_size = buffer.size;
let mut max_alignment = 1;

if self.private_caps.resource_heaps {
// We don't know what memory type the user will try to allocate the buffer with, so we test them
// all get the most stringent ones. Note we don't check Shared because heaps can't use it
for &options in [
MTLResourceStorageModeManaged,
MTLResourceStorageModeManaged | MTLResourceCPUCacheModeWriteCombined,
MTLResourceStorageModePrivate,
].iter() {
let requirements = self.device.heap_buffer_size_and_align(buffer.size, options);
max_size = cmp::max(max_size, requirements.size);
max_alignment = cmp::max(max_alignment, requirements.align);
}
}

memory::Requirements {
size: max_size,
alignment: max_alignment,
Expand Down

0 comments on commit 54e072f

Please sign in to comment.