Skip to content

Commit

Permalink
Use pointers for samplers
Browse files Browse the repository at this point in the history
  • Loading branch information
grovesNL committed Jun 24, 2018
1 parent f9193d7 commit 6966d52
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 56 deletions.
55 changes: 30 additions & 25 deletions src/backend/metal/src/command.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use {AutoreleasePool, Backend, PrivateDisabilities, Shared, validate_line_width, BufferPtr, TexturePtr};
use {
AutoreleasePool, Backend, PrivateDisabilities, Shared, validate_line_width,
BufferPtr, TexturePtr, SamplerPtr,
};
use {conversions as conv, native, soft, window};
use internal::{BlitVertex, Channel, ClearKey, ClearVertex, ServicePipes};

Expand Down Expand Up @@ -208,7 +211,7 @@ impl State {
.zip(render_resources)
.flat_map(move |(&stage, resources)| {
let com_buffers = resources.buffers.iter().enumerate().filter_map(move |(i, resource)| {
resource.as_ref().map(|&(buffer, offset)| {
resource.map(|(buffer, offset)| {
soft::RenderCommand::BindBuffer {
stage,
index: i as _,
Expand All @@ -227,11 +230,11 @@ impl State {
})
});
let com_samplers = resources.samplers.iter().enumerate().filter_map(move |(i, resource)| {
resource.as_ref().map(|sampler| {
resource.map(|sampler| {
soft::RenderCommand::BindSampler {
stage,
index: i as _,
sampler: Some(&**sampler),
sampler: Some(sampler),
}
})
});
Expand Down Expand Up @@ -265,7 +268,7 @@ impl State {
.iter()
.enumerate()
.filter_map(|(i, resource)| {
resource.as_ref().map(|&(buffer, offset)| {
resource.map(|(buffer, offset)| {
soft::ComputeCommand::BindBuffer {
index: i as _,
buffer: Some(buffer),
Expand All @@ -288,10 +291,10 @@ impl State {
.iter()
.enumerate()
.filter_map(|(i, ref resource)| {
resource.as_ref().map(|sampler| {
resource.map(|sampler| {
soft::ComputeCommand::BindSampler {
index: i as _,
sampler: Some(&**sampler),
sampler: Some(sampler),
}
})
});
Expand Down Expand Up @@ -346,7 +349,7 @@ impl State {
.enumerate()
.filter_map(move |(index, maybe_buffer)| {
if mask & (1u64 << index) != 0 {
maybe_buffer.as_ref().map(|&(buffer, offset)| {
maybe_buffer.map(|(buffer, offset)| {
soft::RenderCommand::BindBuffer {
stage: pso::Stage::Vertex,
index,
Expand Down Expand Up @@ -535,7 +538,7 @@ impl State {
struct StageResources {
buffers: Vec<Option<(BufferPtr, buffer::Offset)>>,
textures: Vec<Option<TexturePtr>>,
samplers: Vec<Option<metal::SamplerState>>,
samplers: Vec<Option<SamplerPtr>>,
push_constants_buffer_id: Option<u32>,
}

Expand Down Expand Up @@ -568,16 +571,16 @@ impl StageResources {
self.textures.push(None)
}
for (out, tex) in self.textures[start..].iter_mut().zip(textures.iter()) {
*out = tex.as_ref().map(|&(ref t, _)| t.to_owned());
*out = tex.map(|(t, _)| t);
}
}

fn add_samplers(&mut self, start: usize, samplers: &[Option<metal::SamplerState>]) {
fn add_samplers(&mut self, start: usize, samplers: &[Option<SamplerPtr>]) {
while self.samplers.len() < start + samplers.len() {
self.samplers.push(None)
}
for (out, sampler) in self.samplers[start..].iter_mut().zip(samplers.iter()) {
*out = sampler.clone();
*out = *sampler;
}
}
}
Expand Down Expand Up @@ -948,11 +951,12 @@ fn exec_render<'a>(encoder: &metal::RenderCommandEncoderRef, command: soft::Rend
}
}
Cmd::BindSampler { stage, index, sampler } => {
let native = sampler.as_ref().map(|s| s.as_native());
match stage {
pso::Stage::Vertex =>
encoder.set_vertex_sampler_state(index as _, sampler),
encoder.set_vertex_sampler_state(index as _, native),
pso::Stage::Fragment =>
encoder.set_fragment_sampler_state(index as _, sampler),
encoder.set_fragment_sampler_state(index as _, native),
_ => unimplemented!()
}
}
Expand Down Expand Up @@ -1127,7 +1131,8 @@ fn exec_compute<'a>(encoder: &metal::ComputeCommandEncoderRef, command: soft::Co
encoder.set_texture(index as _, native);
}
Cmd::BindSampler { index, sampler } => {
encoder.set_sampler_state(index as _, sampler);
let native = sampler.as_ref().map(|s| s.as_native());
encoder.set_sampler_state(index as _, native);
}
Cmd::BindPipeline(pipeline) => {
encoder.set_compute_pipeline_state(pipeline);
Expand Down Expand Up @@ -2490,7 +2495,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
soft::RenderCommand::BindSampler {
stage,
index: start + i,
sampler: sampler.as_ref().map(Borrow::borrow),
sampler: *sampler,
}
}));
}
Expand All @@ -2503,7 +2508,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
soft::RenderCommand::BindTexture {
stage,
index: start + i,
texture: texture.as_ref().map(|&(root, _)| root),
texture: texture.map(|(root, _)| root),
}
}));
}
Expand All @@ -2512,18 +2517,18 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
for &mut (stage, ref loc, ref mut resources) in &mut bind_stages {
let start_tx = layout.res_overrides[loc].texture_id as usize;
let start_sm = layout.res_overrides[loc].sampler_id as usize;
for (i, (ref texture, ref sampler)) in combos.iter().enumerate() {
for (i, (texture, sampler)) in combos.iter().enumerate() {
resources.add_textures(start_tx + i, &[texture.clone()]);
resources.add_samplers(start_sm + i, &[sampler.clone()]);
commands.push(soft::RenderCommand::BindTexture {
stage,
index: start_tx + i,
texture: texture.as_ref().map(|&(root, _)| root),
texture: texture.map(|(root, _)| root),
});
commands.push(soft::RenderCommand::BindSampler {
stage,
index: start_sm + i,
sampler: sampler.as_ref().map(Borrow::borrow),
sampler: *sampler,
});
}
}
Expand Down Expand Up @@ -2676,7 +2681,7 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
commands.extend(samplers.iter().enumerate().map(|(i, sampler)| {
soft::ComputeCommand::BindSampler {
index: start + i,
sampler: sampler.as_ref().map(Borrow::borrow),
sampler: *sampler,
}
}));
}
Expand All @@ -2686,23 +2691,23 @@ impl com::RawCommandBuffer<Backend> for CommandBuffer {
commands.extend(images.iter().enumerate().map(|(i, texture)| {
soft::ComputeCommand::BindTexture {
index: start + i,
texture: texture.as_ref().map(|&(root, _)| root),
texture: texture.map(|(root, _)| root),
}
}));
}
Combined(ref combos) => {
for (i, (ref texture, ref sampler)) in combos.iter().enumerate() {
for (i, (texture, sampler)) in combos.iter().enumerate() {
let id_tx = res.texture_id as usize + i;
let id_sm = res.sampler_id as usize + i;
resources.add_textures(id_tx, &[texture.clone()]);
resources.add_samplers(id_sm, &[sampler.clone()]);
commands.push(soft::ComputeCommand::BindTexture {
index: id_tx,
texture: texture.as_ref().map(|&(root, _)| root),
texture: texture.map(|(root, _)| root),
});
commands.push(soft::ComputeCommand::BindSampler {
index: id_sm,
sampler: sampler.as_ref().map(Borrow::borrow),
sampler: *sampler,
});
}
}
Expand Down
16 changes: 10 additions & 6 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, BufferPtr, TexturePtr,
Shared, Surface, Swapchain, validate_line_width, BufferPtr, SamplerPtr, TexturePtr,
};
use {conversions as conv, command, native as n};
use native;
Expand Down Expand Up @@ -1232,12 +1232,16 @@ impl hal::Device<Backend> for Device {
});
}

n::Sampler(
self.shared.device
let raw = self.shared.device
.lock()
.unwrap()
.new_sampler(&descriptor)
)
.new_sampler(&descriptor);
let raw_ptr = raw.as_ptr();
unsafe {
msg_send![raw_ptr as *mut Object, retain];
}

n::Sampler(SamplerPtr(raw_ptr))
}

fn destroy_sampler(&self, _sampler: n::Sampler) {
Expand Down Expand Up @@ -1491,7 +1495,7 @@ impl hal::Device<Backend> for Device {
for descriptor in write.descriptors {
match *descriptor.borrow() {
pso::Descriptor::Sampler(sampler) => {
encoder.set_sampler_states(&[&sampler.0], write.binding as _);
encoder.set_sampler_states(&[&sampler.0.as_native()], write.binding as _);
}
pso::Descriptor::Image(image, _layout) => {
encoder.set_textures(&[image.raw.as_native()], write.binding as _);
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
17 changes: 17 additions & 0 deletions src/backend/metal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,20 @@ impl TexturePtr {
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
}
}
38 changes: 33 additions & 5 deletions src/backend/metal/src/native.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use {Backend, BufferPtr, TexturePtr};
use {Backend, BufferPtr, SamplerPtr, TexturePtr};
use internal::Channel;
use window::SwapchainImage;

Expand Down Expand Up @@ -184,6 +184,13 @@ impl Image {
}
}

impl Drop for Image {
fn drop(&mut self) {
// Own the texture and let it drop/release
let _ = *self.raw.as_native();
}
}

unsafe impl Send for Image {}
unsafe impl Sync for Image {}

Expand All @@ -195,6 +202,13 @@ pub struct BufferView {
unsafe impl Send for BufferView {}
unsafe impl Sync for BufferView {}

impl Drop for BufferView {
fn drop(&mut self) {
// Own the texture and let it drop/release
let _ = *self.raw.as_native();
}
}

#[derive(Debug)]
pub struct ImageView {
pub(crate) raw: TexturePtr,
Expand All @@ -204,8 +218,22 @@ pub struct ImageView {
unsafe impl Send for ImageView {}
unsafe impl Sync for ImageView {}

impl Drop for ImageView {
fn drop(&mut self) {
// Own the texture and let it drop/release
let _ = *self.raw.as_native();
}
}

#[derive(Debug)]
pub struct Sampler(pub(crate) metal::SamplerState);
pub struct Sampler(pub(crate) SamplerPtr);

impl Drop for Sampler {
fn drop(&mut self) {
// Own the sampler and let it drop/release
let _ = *self.0.as_native();
}
}

unsafe impl Send for Sampler {}
unsafe impl Sync for Sampler {}
Expand Down Expand Up @@ -390,7 +418,7 @@ impl hal::DescriptorPool<Backend> for DescriptorPool {

#[derive(Debug)]
pub enum DescriptorSetLayout {
Emulated(Vec<pso::DescriptorSetLayoutBinding>, Vec<metal::SamplerState>),
Emulated(Vec<pso::DescriptorSetLayoutBinding>, Vec<SamplerPtr>),
ArgumentBuffer(metal::ArgumentEncoder, pso::ShaderStageFlags),
}
unsafe impl Send for DescriptorSetLayout {}
Expand Down Expand Up @@ -425,9 +453,9 @@ pub struct BufferBinding {

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

0 comments on commit 6966d52

Please sign in to comment.