Skip to content

Commit 76c15df

Browse files
committed
Use pointers for temporary state
1 parent f2f7c5d commit 76c15df

File tree

7 files changed

+267
-214
lines changed

7 files changed

+267
-214
lines changed

src/backend/metal/src/command.rs

+109-124
Large diffs are not rendered by default.

src/backend/metal/src/device.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use {
22
AutoreleasePool, Backend, PrivateCapabilities, QueueFamily,
3-
Shared, Surface, Swapchain, validate_line_width
3+
Shared, Surface, Swapchain, validate_line_width, BufferPtr, SamplerPtr, TexturePtr,
44
};
55
use {conversions as conv, command, native as n};
66
use native;
@@ -28,6 +28,7 @@ use metal::{self,
2828
CaptureManager
2929
};
3030
use spirv_cross::{msl, spirv, ErrorCode as SpirvErrorCode};
31+
use foreign_types::ForeignType;
3132

3233
use range_alloc::RangeAllocator;
3334

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

13731374
let total_size = encoder.encoded_length();
1374-
let buffer = device.new_buffer(total_size, MTLResourceOptions::empty());
1375+
let raw = device.new_buffer(total_size, MTLResourceOptions::empty());
13751376

13761377
n::DescriptorPool::ArgumentBuffer {
1377-
buffer,
1378+
raw,
13781379
range_allocator: RangeAllocator::new(0..total_size),
13791380
}
13801381
}
@@ -1441,27 +1442,27 @@ impl hal::Device<Backend> for Device {
14411442

14421443
match (descriptor.borrow(), set.bindings[binding as usize].as_mut().unwrap()) {
14431444
(&pso::Descriptor::Sampler(sampler), &mut n::DescriptorSetBinding::Sampler(ref mut vec)) => {
1444-
vec[array_offset] = Some(sampler.0.clone());
1445+
vec[array_offset] = Some(SamplerPtr(sampler.0.as_ptr()));
14451446
}
14461447
(&pso::Descriptor::Image(image, layout), &mut n::DescriptorSetBinding::Image(ref mut vec)) => {
1447-
vec[array_offset] = Some((image.raw.clone(), layout));
1448+
vec[array_offset] = Some((TexturePtr(image.raw.as_ptr()), layout));
14481449
}
14491450
(&pso::Descriptor::Image(image, layout), &mut n::DescriptorSetBinding::Combined(ref mut vec)) => {
1450-
vec[array_offset].0 = Some((image.raw.clone(), layout));
1451+
vec[array_offset].0 = Some((TexturePtr(image.raw.as_ptr()), layout));
14511452
}
14521453
(&pso::Descriptor::CombinedImageSampler(image, layout, sampler), &mut n::DescriptorSetBinding::Combined(ref mut vec)) => {
1453-
vec[array_offset] = (Some((image.raw.clone(), layout)), Some(sampler.0.clone()));
1454+
vec[array_offset] = (Some((TexturePtr(image.raw.as_ptr()), layout)), Some(SamplerPtr(sampler.0.as_ptr())));
14541455
}
14551456
(&pso::Descriptor::UniformTexelBuffer(view), &mut n::DescriptorSetBinding::Image(ref mut vec)) |
14561457
(&pso::Descriptor::StorageTexelBuffer(view), &mut n::DescriptorSetBinding::Image(ref mut vec)) => {
1457-
vec[array_offset] = Some((view.raw.clone(), image::Layout::General));
1458+
vec[array_offset] = Some((TexturePtr(view.raw.as_ptr()), image::Layout::General));
14581459
}
14591460
(&pso::Descriptor::Buffer(buffer, ref range), &mut n::DescriptorSetBinding::Buffer(ref mut vec)) => {
14601461
let buf_length = buffer.raw.length();
14611462
let start = range.start.unwrap_or(0);
14621463
let end = range.end.unwrap_or(buf_length);
14631464
assert!(end <= buf_length);
1464-
vec[array_offset].base = Some((buffer.raw.clone(), start));
1465+
vec[array_offset].base = Some((BufferPtr(buffer.raw.as_ptr()), start));
14651466
}
14661467
(&pso::Descriptor::Sampler(..), _) |
14671468
(&pso::Descriptor::Image(..), _) |
@@ -1474,10 +1475,10 @@ impl hal::Device<Backend> for Device {
14741475
}
14751476
}
14761477
}
1477-
n::DescriptorSet::ArgumentBuffer { ref buffer, offset, ref encoder, .. } => {
1478+
n::DescriptorSet::ArgumentBuffer { ref raw, offset, ref encoder, .. } => {
14781479
debug_assert!(self.private_caps.argument_buffers);
14791480

1480-
encoder.set_argument_buffer(buffer, offset);
1481+
encoder.set_argument_buffer(raw, offset);
14811482
//TODO: range checks, need to keep some layout metadata around
14821483
assert_eq!(write.array_offset, 0); //TODO
14831484

src/backend/metal/src/internal.rs

+23-9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use SamplerPtr;
2+
13
use metal;
24
use hal::backend::FastHashMap;
35
use hal::command::ClearColorRaw;
@@ -8,6 +10,9 @@ use std::mem;
810
use std::path::Path;
911
use std::sync::Mutex;
1012

13+
use objc::runtime::Object;
14+
use foreign_types::ForeignType;
15+
1116
#[derive(Clone, Debug)]
1217
pub struct ClearVertex {
1318
pub pos: [f32; 4],
@@ -71,8 +76,8 @@ impl Channel {
7176

7277

7378
pub struct SamplerStates {
74-
nearest: metal::SamplerState,
75-
linear: metal::SamplerState,
79+
nearest: SamplerPtr,
80+
linear: SamplerPtr,
7681
}
7782

7883
impl SamplerStates {
@@ -81,21 +86,30 @@ impl SamplerStates {
8186
desc.set_min_filter(metal::MTLSamplerMinMagFilter::Nearest);
8287
desc.set_mag_filter(metal::MTLSamplerMinMagFilter::Nearest);
8388
desc.set_mip_filter(metal::MTLSamplerMipFilter::Nearest);
84-
let nearest = device.new_sampler(&desc);
89+
let nearest_raw = device.new_sampler(&desc);
90+
let nearest_raw_ptr = nearest_raw.as_ptr();
91+
unsafe {
92+
msg_send![nearest_raw_ptr as *mut Object, retain];
93+
}
94+
8595
desc.set_min_filter(metal::MTLSamplerMinMagFilter::Linear);
8696
desc.set_mag_filter(metal::MTLSamplerMinMagFilter::Linear);
87-
let linear = device.new_sampler(&desc);
97+
let linear_raw = device.new_sampler(&desc);
98+
let linear_raw_ptr = linear_raw.as_ptr();
99+
unsafe {
100+
msg_send![linear_raw_ptr as *mut Object, retain];
101+
}
88102

89103
SamplerStates {
90-
nearest,
91-
linear,
104+
nearest: SamplerPtr(nearest_raw_ptr),
105+
linear: SamplerPtr(linear_raw_ptr),
92106
}
93107
}
94108

95-
pub fn get(&self, filter: Filter) -> &metal::SamplerStateRef {
109+
pub fn get(&self, filter: Filter) -> SamplerPtr {
96110
match filter {
97-
Filter::Nearest => &self.nearest,
98-
Filter::Linear => &self.linear,
111+
Filter::Nearest => self.nearest,
112+
Filter::Linear => self.linear,
99113
}
100114
}
101115
}

src/backend/metal/src/lib.rs

+52
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use hal::queue::QueueFamilyId;
4343
use objc::runtime::{Class, Object};
4444
use cocoa::foundation::NSAutoreleasePool;
4545
use core_graphics::geometry::CGRect;
46+
use foreign_types::ForeignTypeRef;
4647

4748

4849
const MAX_ACTIVE_COMMAND_BUFFERS: usize = 1 << 14;
@@ -252,3 +253,54 @@ fn validate_line_width(width: f32) {
252253
// Simply assert and no-op because Metal never exposes `Features::LINE_WIDTH`
253254
assert_eq!(width, 1.0);
254255
}
256+
257+
#[derive(Clone, Copy, Debug)]
258+
pub struct BufferPtr(*mut metal::MTLBuffer);
259+
260+
impl BufferPtr {
261+
#[inline]
262+
pub fn as_native(&self) -> &metal::BufferRef {
263+
unsafe {
264+
metal::BufferRef::from_ptr(self.0)
265+
}
266+
}
267+
268+
#[inline]
269+
pub fn as_ptr(&self) -> *mut metal::MTLBuffer {
270+
self.0
271+
}
272+
}
273+
274+
#[derive(Clone, Copy, Debug)]
275+
pub struct TexturePtr(*mut metal::MTLTexture);
276+
277+
impl TexturePtr {
278+
#[inline]
279+
pub fn as_native(&self) -> &metal::TextureRef {
280+
unsafe {
281+
metal::TextureRef::from_ptr(self.0)
282+
}
283+
}
284+
285+
#[inline]
286+
pub fn as_ptr(&self) -> *mut metal::MTLTexture {
287+
self.0
288+
}
289+
}
290+
291+
#[derive(Clone, Copy, Debug)]
292+
pub struct SamplerPtr(*mut metal::MTLSamplerState);
293+
294+
impl SamplerPtr {
295+
#[inline]
296+
pub fn as_native(&self) -> &metal::SamplerStateRef {
297+
unsafe {
298+
metal::SamplerStateRef::from_ptr(self.0)
299+
}
300+
}
301+
302+
#[inline]
303+
pub fn as_ptr(&self) -> *mut metal::MTLSamplerState {
304+
self.0
305+
}
306+
}

src/backend/metal/src/native.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use Backend;
1+
use {Backend, BufferPtr, SamplerPtr, TexturePtr};
22
use internal::Channel;
33
use window::SwapchainImage;
44

@@ -14,6 +14,7 @@ use hal::format::{Aspects, Format, FormatDesc};
1414
use cocoa::foundation::{NSUInteger};
1515
use metal;
1616
use spirv_cross::{msl, spirv};
17+
use foreign_types::ForeignType;
1718

1819
use range_alloc::RangeAllocator;
1920

@@ -231,7 +232,7 @@ unsafe impl Sync for Buffer {}
231232
pub enum DescriptorPool {
232233
Emulated,
233234
ArgumentBuffer {
234-
buffer: metal::Buffer,
235+
raw: metal::Buffer,
235236
range_allocator: RangeAllocator<NSUInteger>,
236237
}
237238
}
@@ -260,7 +261,7 @@ impl hal::DescriptorPool<Backend> for DescriptorPool {
260261
sampler_offset += layout.count;
261262
slice
262263
.iter()
263-
.map(|s| Some(s.clone()))
264+
.map(|s| Some(SamplerPtr(s.as_ptr())))
264265
.collect()
265266
} else {
266267
vec![None; layout.count]
@@ -272,7 +273,7 @@ impl hal::DescriptorPool<Backend> for DescriptorPool {
272273
sampler_offset += layout.count;
273274
slice
274275
.iter()
275-
.map(|s| (None, Some(s.clone())))
276+
.map(|s| (None, Some(SamplerPtr(s.as_ptr()))))
276277
.collect()
277278
} else {
278279
vec![(None, None); layout.count]
@@ -313,14 +314,14 @@ impl hal::DescriptorPool<Backend> for DescriptorPool {
313314
};
314315
Ok(DescriptorSet::Emulated(Arc::new(Mutex::new(inner))))
315316
}
316-
DescriptorPool::ArgumentBuffer { ref buffer, ref mut range_allocator, } => {
317+
DescriptorPool::ArgumentBuffer { ref raw, ref mut range_allocator, } => {
317318
let (encoder, stage_flags) = match layout {
318319
&DescriptorSetLayout::ArgumentBuffer(ref encoder, stages) => (encoder, stages),
319320
_ => return Err(pso::AllocationError::IncompatibleLayout),
320321
};
321322
range_allocator.allocate_range(encoder.encoded_length()).map(|range| {
322323
DescriptorSet::ArgumentBuffer {
323-
buffer: buffer.clone(),
324+
raw: raw.clone(),
324325
offset: range.start,
325326
encoder: encoder.clone(),
326327
stage_flags,
@@ -381,7 +382,7 @@ unsafe impl Sync for DescriptorSetLayout {}
381382
pub enum DescriptorSet {
382383
Emulated(Arc<Mutex<DescriptorSetInner>>),
383384
ArgumentBuffer {
384-
buffer: metal::Buffer,
385+
raw: metal::Buffer,
385386
offset: NSUInteger,
386387
encoder: metal::ArgumentEncoder,
387388
stage_flags: pso::ShaderStageFlags,
@@ -400,17 +401,17 @@ unsafe impl Send for DescriptorSetInner {}
400401

401402
#[derive(Clone, Debug)]
402403
pub struct BufferBinding {
403-
pub base: Option<(metal::Buffer, u64)>,
404+
pub base: Option<(BufferPtr, u64)>,
404405
pub dynamic: bool,
405406
}
406407

407408
#[derive(Clone, Debug)]
408409
pub enum DescriptorSetBinding {
409-
Sampler(Vec<Option<metal::SamplerState>>),
410-
Image(Vec<Option<(metal::Texture, image::Layout)>>),
411-
Combined(Vec<(Option<(metal::Texture, image::Layout)>, Option<metal::SamplerState>)>),
410+
Sampler(Vec<Option<SamplerPtr>>),
411+
Image(Vec<Option<(TexturePtr, image::Layout)>>),
412+
Combined(Vec<(Option<(TexturePtr, image::Layout)>, Option<SamplerPtr>)>),
412413
Buffer(Vec<BufferBinding>),
413-
//InputAttachment(Vec<(metal::Texture, image::Layout)>),
414+
//InputAttachment(Vec<(TexturePtr, image::Layout)>),
414415
}
415416

416417
impl DescriptorSetBinding {

0 commit comments

Comments
 (0)