Skip to content

Commit

Permalink
Use pointers for temporary state
Browse files Browse the repository at this point in the history
  • Loading branch information
grovesNL committed Jun 24, 2018
1 parent f2f7c5d commit 76c15df
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 214 deletions.
233 changes: 109 additions & 124 deletions src/backend/metal/src/command.rs

Large diffs are not rendered by default.

25 changes: 13 additions & 12 deletions src/backend/metal/src/device.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use {
AutoreleasePool, Backend, PrivateCapabilities, QueueFamily,
Shared, Surface, Swapchain, validate_line_width
Shared, Surface, Swapchain, validate_line_width, BufferPtr, SamplerPtr, TexturePtr,
};
use {conversions as conv, command, native as n};
use native;
Expand Down Expand Up @@ -28,6 +28,7 @@ use metal::{self,
CaptureManager
};
use spirv_cross::{msl, spirv, ErrorCode as SpirvErrorCode};
use foreign_types::ForeignType;

use range_alloc::RangeAllocator;

Expand Down Expand Up @@ -1309,7 +1310,7 @@ impl hal::Device<Backend> for Device {
n::MemoryHeap::Native(_) => unimplemented!(),
n::MemoryHeap::Public(mt, ref cpu_buffer) if 1<<mt.0 != MemoryTypes::SHARED.bits() as usize => {
num_syncs += 1;
encoder.synchronize_resource(cpu_buffer.as_ref());
encoder.synchronize_resource(cpu_buffer);
}
n::MemoryHeap::Public(..) => continue,
n::MemoryHeap::Private => panic!("Can't map private memory!"),
Expand Down Expand Up @@ -1371,10 +1372,10 @@ impl hal::Device<Backend> for Device {
let encoder = device.new_argument_encoder(&arg_array);

let total_size = encoder.encoded_length();
let buffer = device.new_buffer(total_size, MTLResourceOptions::empty());
let raw = device.new_buffer(total_size, MTLResourceOptions::empty());

n::DescriptorPool::ArgumentBuffer {
buffer,
raw,
range_allocator: RangeAllocator::new(0..total_size),
}
}
Expand Down Expand Up @@ -1441,27 +1442,27 @@ impl hal::Device<Backend> for Device {

match (descriptor.borrow(), set.bindings[binding as usize].as_mut().unwrap()) {
(&pso::Descriptor::Sampler(sampler), &mut n::DescriptorSetBinding::Sampler(ref mut vec)) => {
vec[array_offset] = Some(sampler.0.clone());
vec[array_offset] = Some(SamplerPtr(sampler.0.as_ptr()));
}
(&pso::Descriptor::Image(image, layout), &mut n::DescriptorSetBinding::Image(ref mut vec)) => {
vec[array_offset] = Some((image.raw.clone(), layout));
vec[array_offset] = Some((TexturePtr(image.raw.as_ptr()), layout));
}
(&pso::Descriptor::Image(image, layout), &mut n::DescriptorSetBinding::Combined(ref mut vec)) => {
vec[array_offset].0 = Some((image.raw.clone(), layout));
vec[array_offset].0 = Some((TexturePtr(image.raw.as_ptr()), layout));
}
(&pso::Descriptor::CombinedImageSampler(image, layout, sampler), &mut n::DescriptorSetBinding::Combined(ref mut vec)) => {
vec[array_offset] = (Some((image.raw.clone(), layout)), Some(sampler.0.clone()));
vec[array_offset] = (Some((TexturePtr(image.raw.as_ptr()), layout)), Some(SamplerPtr(sampler.0.as_ptr())));
}
(&pso::Descriptor::UniformTexelBuffer(view), &mut n::DescriptorSetBinding::Image(ref mut vec)) |
(&pso::Descriptor::StorageTexelBuffer(view), &mut n::DescriptorSetBinding::Image(ref mut vec)) => {
vec[array_offset] = Some((view.raw.clone(), image::Layout::General));
vec[array_offset] = Some((TexturePtr(view.raw.as_ptr()), image::Layout::General));
}
(&pso::Descriptor::Buffer(buffer, ref range), &mut n::DescriptorSetBinding::Buffer(ref mut vec)) => {
let buf_length = buffer.raw.length();
let start = range.start.unwrap_or(0);
let end = range.end.unwrap_or(buf_length);
assert!(end <= buf_length);
vec[array_offset].base = Some((buffer.raw.clone(), start));
vec[array_offset].base = Some((BufferPtr(buffer.raw.as_ptr()), start));
}
(&pso::Descriptor::Sampler(..), _) |
(&pso::Descriptor::Image(..), _) |
Expand All @@ -1474,10 +1475,10 @@ impl hal::Device<Backend> for Device {
}
}
}
n::DescriptorSet::ArgumentBuffer { ref buffer, offset, ref encoder, .. } => {
n::DescriptorSet::ArgumentBuffer { ref raw, offset, ref encoder, .. } => {
debug_assert!(self.private_caps.argument_buffers);

encoder.set_argument_buffer(buffer, offset);
encoder.set_argument_buffer(raw, offset);
//TODO: range checks, need to keep some layout metadata around
assert_eq!(write.array_offset, 0); //TODO

Expand Down
32 changes: 23 additions & 9 deletions src/backend/metal/src/internal.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use SamplerPtr;

use metal;
use hal::backend::FastHashMap;
use hal::command::ClearColorRaw;
Expand All @@ -8,6 +10,9 @@ use std::mem;
use std::path::Path;
use std::sync::Mutex;

use objc::runtime::Object;
use foreign_types::ForeignType;

#[derive(Clone, Debug)]
pub struct ClearVertex {
pub pos: [f32; 4],
Expand Down Expand Up @@ -71,8 +76,8 @@ impl Channel {


pub struct SamplerStates {
nearest: metal::SamplerState,
linear: metal::SamplerState,
nearest: SamplerPtr,
linear: SamplerPtr,
}

impl SamplerStates {
Expand All @@ -81,21 +86,30 @@ impl SamplerStates {
desc.set_min_filter(metal::MTLSamplerMinMagFilter::Nearest);
desc.set_mag_filter(metal::MTLSamplerMinMagFilter::Nearest);
desc.set_mip_filter(metal::MTLSamplerMipFilter::Nearest);
let nearest = device.new_sampler(&desc);
let nearest_raw = device.new_sampler(&desc);
let nearest_raw_ptr = nearest_raw.as_ptr();
unsafe {
msg_send![nearest_raw_ptr as *mut Object, retain];
}

desc.set_min_filter(metal::MTLSamplerMinMagFilter::Linear);
desc.set_mag_filter(metal::MTLSamplerMinMagFilter::Linear);
let linear = device.new_sampler(&desc);
let linear_raw = device.new_sampler(&desc);
let linear_raw_ptr = linear_raw.as_ptr();
unsafe {
msg_send![linear_raw_ptr as *mut Object, retain];
}

SamplerStates {
nearest,
linear,
nearest: SamplerPtr(nearest_raw_ptr),
linear: SamplerPtr(linear_raw_ptr),
}
}

pub fn get(&self, filter: Filter) -> &metal::SamplerStateRef {
pub fn get(&self, filter: Filter) -> SamplerPtr {
match filter {
Filter::Nearest => &self.nearest,
Filter::Linear => &self.linear,
Filter::Nearest => self.nearest,
Filter::Linear => self.linear,
}
}
}
Expand Down
52 changes: 52 additions & 0 deletions src/backend/metal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use hal::queue::QueueFamilyId;
use objc::runtime::{Class, Object};
use cocoa::foundation::NSAutoreleasePool;
use core_graphics::geometry::CGRect;
use foreign_types::ForeignTypeRef;


const MAX_ACTIVE_COMMAND_BUFFERS: usize = 1 << 14;
Expand Down Expand Up @@ -252,3 +253,54 @@ fn validate_line_width(width: f32) {
// Simply assert and no-op because Metal never exposes `Features::LINE_WIDTH`
assert_eq!(width, 1.0);
}

#[derive(Clone, Copy, Debug)]
pub struct BufferPtr(*mut metal::MTLBuffer);

impl BufferPtr {
#[inline]
pub fn as_native(&self) -> &metal::BufferRef {
unsafe {
metal::BufferRef::from_ptr(self.0)
}
}

#[inline]
pub fn as_ptr(&self) -> *mut metal::MTLBuffer {
self.0
}
}

#[derive(Clone, Copy, Debug)]
pub struct TexturePtr(*mut metal::MTLTexture);

impl TexturePtr {
#[inline]
pub fn as_native(&self) -> &metal::TextureRef {
unsafe {
metal::TextureRef::from_ptr(self.0)
}
}

#[inline]
pub fn as_ptr(&self) -> *mut metal::MTLTexture {
self.0
}
}

#[derive(Clone, Copy, Debug)]
pub struct SamplerPtr(*mut metal::MTLSamplerState);

impl SamplerPtr {
#[inline]
pub fn as_native(&self) -> &metal::SamplerStateRef {
unsafe {
metal::SamplerStateRef::from_ptr(self.0)
}
}

#[inline]
pub fn as_ptr(&self) -> *mut metal::MTLSamplerState {
self.0
}
}
25 changes: 13 additions & 12 deletions src/backend/metal/src/native.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use Backend;
use {Backend, BufferPtr, SamplerPtr, TexturePtr};
use internal::Channel;
use window::SwapchainImage;

Expand All @@ -14,6 +14,7 @@ use hal::format::{Aspects, Format, FormatDesc};
use cocoa::foundation::{NSUInteger};
use metal;
use spirv_cross::{msl, spirv};
use foreign_types::ForeignType;

use range_alloc::RangeAllocator;

Expand Down Expand Up @@ -231,7 +232,7 @@ unsafe impl Sync for Buffer {}
pub enum DescriptorPool {
Emulated,
ArgumentBuffer {
buffer: metal::Buffer,
raw: metal::Buffer,
range_allocator: RangeAllocator<NSUInteger>,
}
}
Expand Down Expand Up @@ -260,7 +261,7 @@ impl hal::DescriptorPool<Backend> for DescriptorPool {
sampler_offset += layout.count;
slice
.iter()
.map(|s| Some(s.clone()))
.map(|s| Some(SamplerPtr(s.as_ptr())))
.collect()
} else {
vec![None; layout.count]
Expand All @@ -272,7 +273,7 @@ impl hal::DescriptorPool<Backend> for DescriptorPool {
sampler_offset += layout.count;
slice
.iter()
.map(|s| (None, Some(s.clone())))
.map(|s| (None, Some(SamplerPtr(s.as_ptr()))))
.collect()
} else {
vec![(None, None); layout.count]
Expand Down Expand Up @@ -313,14 +314,14 @@ impl hal::DescriptorPool<Backend> for DescriptorPool {
};
Ok(DescriptorSet::Emulated(Arc::new(Mutex::new(inner))))
}
DescriptorPool::ArgumentBuffer { ref buffer, ref mut range_allocator, } => {
DescriptorPool::ArgumentBuffer { ref raw, ref mut range_allocator, } => {
let (encoder, stage_flags) = match layout {
&DescriptorSetLayout::ArgumentBuffer(ref encoder, stages) => (encoder, stages),
_ => return Err(pso::AllocationError::IncompatibleLayout),
};
range_allocator.allocate_range(encoder.encoded_length()).map(|range| {
DescriptorSet::ArgumentBuffer {
buffer: buffer.clone(),
raw: raw.clone(),
offset: range.start,
encoder: encoder.clone(),
stage_flags,
Expand Down Expand Up @@ -381,7 +382,7 @@ unsafe impl Sync for DescriptorSetLayout {}
pub enum DescriptorSet {
Emulated(Arc<Mutex<DescriptorSetInner>>),
ArgumentBuffer {
buffer: metal::Buffer,
raw: metal::Buffer,
offset: NSUInteger,
encoder: metal::ArgumentEncoder,
stage_flags: pso::ShaderStageFlags,
Expand All @@ -400,17 +401,17 @@ unsafe impl Send for DescriptorSetInner {}

#[derive(Clone, Debug)]
pub struct BufferBinding {
pub base: Option<(metal::Buffer, u64)>,
pub base: Option<(BufferPtr, u64)>,
pub dynamic: bool,
}

#[derive(Clone, Debug)]
pub enum DescriptorSetBinding {
Sampler(Vec<Option<metal::SamplerState>>),
Image(Vec<Option<(metal::Texture, image::Layout)>>),
Combined(Vec<(Option<(metal::Texture, image::Layout)>, Option<metal::SamplerState>)>),
Sampler(Vec<Option<SamplerPtr>>),
Image(Vec<Option<(TexturePtr, image::Layout)>>),
Combined(Vec<(Option<(TexturePtr, image::Layout)>, Option<SamplerPtr>)>),
Buffer(Vec<BufferBinding>),
//InputAttachment(Vec<(metal::Texture, image::Layout)>),
//InputAttachment(Vec<(TexturePtr, image::Layout)>),
}

impl DescriptorSetBinding {
Expand Down
Loading

0 comments on commit 76c15df

Please sign in to comment.