mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-10-30 05:51:42 +00:00
hal/mtl: queue
This commit is contained in:
parent
3109b1b63d
commit
782c72d32c
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1916,6 +1916,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags",
|
||||
"block",
|
||||
"foreign-types",
|
||||
"log",
|
||||
"metal",
|
||||
|
@ -48,6 +48,7 @@ version = "0.8"
|
||||
path = "../wgpu-hal"
|
||||
package = "wgpu-hal"
|
||||
version = "0.1"
|
||||
features = ["empty"]
|
||||
|
||||
[target.'cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))'.dependencies]
|
||||
hal = { path = "../wgpu-hal", package = "wgpu-hal", features = ["metal"] }
|
||||
|
@ -87,12 +87,14 @@ impl<A: hal::Api> QueryResetMap<A> {
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum SimplifiedQueryType {
|
||||
Occlusion,
|
||||
Timestamp,
|
||||
PipelineStatistics,
|
||||
}
|
||||
impl From<wgt::QueryType> for SimplifiedQueryType {
|
||||
fn from(q: wgt::QueryType) -> Self {
|
||||
match q {
|
||||
wgt::QueryType::Occlusion => SimplifiedQueryType::Occlusion,
|
||||
wgt::QueryType::Timestamp => SimplifiedQueryType::Timestamp,
|
||||
wgt::QueryType::PipelineStatistics(..) => SimplifiedQueryType::PipelineStatistics,
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ pub const SHADER_STAGE_COUNT: usize = 3;
|
||||
const CLEANUP_WAIT_MS: u32 = 5000;
|
||||
|
||||
const IMPLICIT_FAILURE: &str = "failed implicit";
|
||||
const EP_FAILURE: &str = "EP is invalid";
|
||||
|
||||
pub type DeviceDescriptor<'a> = wgt::DeviceDescriptor<Label<'a>>;
|
||||
|
||||
@ -1719,6 +1720,9 @@ impl<A: HalApi> Device<A> {
|
||||
hal::PipelineError::Linkage(_stages, msg) => {
|
||||
pipeline::CreateComputePipelineError::Internal(msg)
|
||||
}
|
||||
hal::PipelineError::EntryPoint(_stage) => {
|
||||
pipeline::CreateComputePipelineError::Internal(EP_FAILURE.to_string())
|
||||
}
|
||||
},
|
||||
)?;
|
||||
|
||||
@ -2097,6 +2101,12 @@ impl<A: HalApi> Device<A> {
|
||||
hal::PipelineError::Linkage(stage, msg) => {
|
||||
pipeline::CreateRenderPipelineError::Internal { stage, error: msg }
|
||||
}
|
||||
hal::PipelineError::EntryPoint(stage) => {
|
||||
pipeline::CreateRenderPipelineError::Internal {
|
||||
stage: hal::aux::map_naga_stage(stage),
|
||||
error: EP_FAILURE.to_string(),
|
||||
}
|
||||
}
|
||||
},
|
||||
)?;
|
||||
|
||||
|
@ -12,8 +12,9 @@ license = "MIT OR Apache-2.0"
|
||||
[lib]
|
||||
|
||||
[features]
|
||||
default = ["metal"]
|
||||
metal = ["foreign-types", "mtl", "objc", "parking_lot", "naga/msl-out"]
|
||||
default = []
|
||||
empty = []
|
||||
metal = ["block", "foreign-types", "mtl", "objc", "parking_lot", "naga/msl-out"]
|
||||
|
||||
[dependencies]
|
||||
arrayvec = "0.5"
|
||||
@ -25,6 +26,7 @@ thiserror = "1"
|
||||
wgt = { package = "wgpu-types", path = "../wgpu-types" }
|
||||
|
||||
# backends
|
||||
block = { version = "0.1", optional = true }
|
||||
foreign-types = { version = "0.3", optional = true }
|
||||
mtl = { package = "metal", version = "0.22", optional = true }
|
||||
objc = { version = "0.2.5", optional = true }
|
||||
|
@ -91,10 +91,7 @@ impl<A: hal::Api> Example<A> {
|
||||
};
|
||||
let shader_desc = hal::ShaderModuleDescriptor { label: None };
|
||||
let shader = unsafe {
|
||||
match device.create_shader_module(&shader_desc, naga_shader) {
|
||||
Ok(shader) => shader,
|
||||
Err((error, _shader)) => panic!("{}", error),
|
||||
}
|
||||
device.create_shader_module(&shader_desc, naga_shader).unwrap()
|
||||
};
|
||||
|
||||
let global_bgl_desc = hal::BindGroupLayoutDescriptor {
|
||||
@ -379,10 +376,10 @@ impl<A: hal::Api> Example<A> {
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let fence = device.create_fence().unwrap();
|
||||
let mut fence = device.create_fence().unwrap();
|
||||
init_cmd.finish();
|
||||
queue
|
||||
.submit(iter::once(init_cmd), Some((&fence, 1)))
|
||||
.submit(iter::once(init_cmd), Some((&mut fence, 1)))
|
||||
.unwrap();
|
||||
device.wait(&fence, 1, !0).unwrap();
|
||||
device.destroy_fence(fence);
|
||||
@ -528,6 +525,9 @@ impl<A: hal::Api> Example<A> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "metal")]
|
||||
type Api = hal::api::Metal;
|
||||
|
||||
fn main() {
|
||||
let event_loop = winit::event_loop::EventLoop::new();
|
||||
let window = winit::window::WindowBuilder::new()
|
||||
@ -535,10 +535,7 @@ fn main() {
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
|
||||
#[cfg(feature = "metal")]
|
||||
let example_result = Example::<hal::api::Metal>::init(&window);
|
||||
#[cfg(not(any(feature = "metal")))]
|
||||
let example_result = Example::<hal::api::Empty>::init(&window);
|
||||
let example_result = Example::<Api>::init(&window);
|
||||
let mut example = example_result.expect("Selected backend is not supported");
|
||||
|
||||
let mut last_frame_inst = Instant::now();
|
||||
|
@ -92,7 +92,7 @@ impl crate::Queue<Api> for Context {
|
||||
unsafe fn submit<I>(
|
||||
&mut self,
|
||||
command_buffers: I,
|
||||
signal_fence: Option<(&Resource, crate::FenceValue)>,
|
||||
signal_fence: Option<(&mut Resource, crate::FenceValue)>,
|
||||
) -> DeviceResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
@ -364,7 +364,7 @@ impl crate::CommandBuffer<Api> for Encoder {
|
||||
|
||||
// compute
|
||||
|
||||
unsafe fn begin_compute_pass(&mut self) {}
|
||||
unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor) {}
|
||||
unsafe fn end_compute_pass(&mut self) {}
|
||||
|
||||
unsafe fn set_compute_pipeline(&mut self, pipeline: &Resource) {}
|
||||
|
@ -37,11 +37,13 @@
|
||||
)]
|
||||
|
||||
pub mod aux;
|
||||
pub mod empty;
|
||||
#[cfg(feature = "empty")]
|
||||
mod empty;
|
||||
#[cfg(feature = "metal")]
|
||||
mod metal;
|
||||
|
||||
pub mod api {
|
||||
#[cfg(feature = "empty")]
|
||||
pub use super::empty::Api as Empty;
|
||||
#[cfg(feature = "metal")]
|
||||
pub use super::metal::Api as Metal;
|
||||
@ -128,15 +130,15 @@ pub trait Api: Clone + Sized {
|
||||
type QuerySet: fmt::Debug + Send + Sync;
|
||||
type Fence: fmt::Debug + Send + Sync;
|
||||
|
||||
type BindGroupLayout;
|
||||
type BindGroupLayout: Send + Sync;
|
||||
type BindGroup: fmt::Debug + Send + Sync;
|
||||
type PipelineLayout;
|
||||
type PipelineLayout: Send + Sync;
|
||||
type ShaderModule: fmt::Debug + Send + Sync;
|
||||
type RenderPipeline;
|
||||
type ComputePipeline;
|
||||
type RenderPipeline: Send + Sync;
|
||||
type ComputePipeline: Send + Sync;
|
||||
}
|
||||
|
||||
pub trait Instance<A: Api>: Sized {
|
||||
pub trait Instance<A: Api>: Sized + Send + Sync {
|
||||
unsafe fn init() -> Result<Self, InstanceError>;
|
||||
unsafe fn create_surface(
|
||||
&self,
|
||||
@ -146,7 +148,7 @@ pub trait Instance<A: Api>: Sized {
|
||||
unsafe fn enumerate_adapters(&self) -> Vec<ExposedAdapter<A>>;
|
||||
}
|
||||
|
||||
pub trait Surface<A: Api> {
|
||||
pub trait Surface<A: Api>: Send + Sync {
|
||||
unsafe fn configure(
|
||||
&mut self,
|
||||
device: &A::Device,
|
||||
@ -163,7 +165,7 @@ pub trait Surface<A: Api> {
|
||||
unsafe fn discard_texture(&mut self, texture: A::SurfaceTexture);
|
||||
}
|
||||
|
||||
pub trait Adapter<A: Api> {
|
||||
pub trait Adapter<A: Api>: Send + Sync {
|
||||
unsafe fn open(&self, features: wgt::Features) -> Result<OpenDevice<A>, DeviceError>;
|
||||
unsafe fn close(&self, device: A::Device);
|
||||
|
||||
@ -179,7 +181,7 @@ pub trait Adapter<A: Api> {
|
||||
unsafe fn surface_capabilities(&self, surface: &A::Surface) -> Option<SurfaceCapabilities>;
|
||||
}
|
||||
|
||||
pub trait Device<A: Api> {
|
||||
pub trait Device<A: Api>: Send + Sync {
|
||||
/// Creates a new buffer.
|
||||
///
|
||||
/// The initial usage is `BufferUse::empty()`.
|
||||
@ -275,12 +277,14 @@ pub trait Device<A: Api> {
|
||||
unsafe fn stop_capture(&self);
|
||||
}
|
||||
|
||||
pub trait Queue<A: Api> {
|
||||
unsafe fn submit<I: Iterator<Item = A::CommandBuffer>>(
|
||||
pub trait Queue<A: Api>: Send + Sync {
|
||||
unsafe fn submit<I>(
|
||||
&mut self,
|
||||
command_buffers: I,
|
||||
signal_fence: Option<(&A::Fence, FenceValue)>,
|
||||
) -> Result<(), DeviceError>;
|
||||
signal_fence: Option<(&mut A::Fence, FenceValue)>,
|
||||
) -> Result<(), DeviceError>
|
||||
where
|
||||
I: Iterator<Item = A::CommandBuffer>;
|
||||
unsafe fn present(
|
||||
&mut self,
|
||||
surface: &mut A::Surface,
|
||||
@ -288,9 +292,7 @@ pub trait Queue<A: Api> {
|
||||
) -> Result<(), SurfaceError>;
|
||||
}
|
||||
|
||||
pub trait SwapChain<A: Api> {}
|
||||
|
||||
pub trait CommandBuffer<A: Api> {
|
||||
pub trait CommandBuffer<A: Api>: Send + Sync {
|
||||
unsafe fn finish(&mut self);
|
||||
|
||||
unsafe fn transition_buffers<'a, T>(&mut self, barriers: T)
|
||||
@ -437,7 +439,7 @@ pub trait CommandBuffer<A: Api> {
|
||||
// compute passes
|
||||
|
||||
// Begins a compute pass, clears all active bindings.
|
||||
unsafe fn begin_compute_pass(&mut self);
|
||||
unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor);
|
||||
unsafe fn end_compute_pass(&mut self);
|
||||
|
||||
unsafe fn set_compute_pipeline(&mut self, pipeline: &A::ComputePipeline);
|
||||
@ -988,6 +990,11 @@ pub struct RenderPassDescriptor<'a, A: Api> {
|
||||
pub depth_stencil_attachment: Option<DepthStencilAttachment<'a, A>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ComputePassDescriptor<'a> {
|
||||
pub label: Label<'a>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_limits() {
|
||||
let limits = wgt::Limits::default();
|
||||
|
@ -22,7 +22,9 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
shared: Arc::clone(&self.shared),
|
||||
features,
|
||||
},
|
||||
queue: super::Queue {},
|
||||
queue: super::Queue {
|
||||
shared: Arc::clone(&self.shared),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -470,11 +470,51 @@ impl crate::CommandBuffer<super::Api> for super::CommandBuffer {
|
||||
index: u32,
|
||||
binding: crate::BufferBinding<'a, super::Api>,
|
||||
) {
|
||||
let buffer_index = self.max_buffers_per_stage as u64 - 1 - index as u64;
|
||||
let encoder = self.render.as_ref().unwrap();
|
||||
encoder.set_vertex_buffer(buffer_index, Some(&binding.buffer.raw), binding.offset);
|
||||
}
|
||||
|
||||
unsafe fn set_viewport(&mut self, rect: &crate::Rect<f32>, depth_range: Range<f32>) {
|
||||
let zfar = if self.disabilities.broken_viewport_near_depth {
|
||||
depth_range.end - depth_range.start
|
||||
} else {
|
||||
depth_range.end
|
||||
};
|
||||
let encoder = self.render.as_ref().unwrap();
|
||||
encoder.set_viewport(mtl::MTLViewport {
|
||||
originX: rect.x as _,
|
||||
originY: rect.y as _,
|
||||
width: rect.w as _,
|
||||
height: rect.h as _,
|
||||
znear: depth_range.start as _,
|
||||
zfar: zfar as _,
|
||||
});
|
||||
}
|
||||
unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect<u32>) {
|
||||
//TODO: support empty scissors by modifying the viewport
|
||||
let scissor = mtl::MTLScissorRect {
|
||||
x: rect.x as _,
|
||||
y: rect.y as _,
|
||||
width: rect.w as _,
|
||||
height: rect.h as _,
|
||||
};
|
||||
let encoder = self.render.as_ref().unwrap();
|
||||
encoder.set_scissor_rect(scissor);
|
||||
}
|
||||
unsafe fn set_stencil_reference(&mut self, value: u32) {
|
||||
let encoder = self.render.as_ref().unwrap();
|
||||
encoder.set_stencil_front_back_reference_value(value, value);
|
||||
}
|
||||
unsafe fn set_blend_constants(&mut self, color: &wgt::Color) {
|
||||
let encoder = self.render.as_ref().unwrap();
|
||||
encoder.set_blend_color(
|
||||
color.r as f32,
|
||||
color.g as f32,
|
||||
color.b as f32,
|
||||
color.a as f32,
|
||||
);
|
||||
}
|
||||
unsafe fn set_viewport(&mut self, rect: &crate::Rect<f32>, depth_range: Range<f32>) {}
|
||||
unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect<u32>) {}
|
||||
unsafe fn set_stencil_reference(&mut self, value: u32) {}
|
||||
unsafe fn set_blend_constants(&mut self, color: &wgt::Color) {}
|
||||
|
||||
unsafe fn draw(
|
||||
&mut self,
|
||||
@ -607,9 +647,12 @@ impl crate::CommandBuffer<super::Api> for super::CommandBuffer {
|
||||
|
||||
// compute
|
||||
|
||||
unsafe fn begin_compute_pass(&mut self) {
|
||||
unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor) {
|
||||
self.leave_blit();
|
||||
let encoder = self.raw.new_compute_command_encoder();
|
||||
if let Some(label) = desc.label {
|
||||
encoder.set_label(label);
|
||||
}
|
||||
self.compute = Some(encoder.to_owned());
|
||||
}
|
||||
unsafe fn end_compute_pass(&mut self) {
|
||||
|
@ -266,7 +266,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
None => texture.array_layers - desc.range.base_array_layer,
|
||||
};
|
||||
|
||||
texture.raw.new_texture_view_from_slice(
|
||||
let raw = texture.raw.new_texture_view_from_slice(
|
||||
raw_format,
|
||||
raw_type,
|
||||
mtl::NSRange {
|
||||
@ -277,7 +277,11 @@ impl crate::Device<super::Api> for super::Device {
|
||||
location: desc.range.base_array_layer as _,
|
||||
length: array_layer_count as _,
|
||||
},
|
||||
)
|
||||
);
|
||||
if let Some(label) = desc.label {
|
||||
raw.set_label(label);
|
||||
}
|
||||
raw
|
||||
};
|
||||
|
||||
let aspects = crate::FormatAspect::from(desc.format);
|
||||
@ -327,6 +331,9 @@ impl crate::Device<super::Api> for super::Device {
|
||||
descriptor.set_border_color(conv::map_border_color(border_color));
|
||||
}
|
||||
|
||||
if let Some(label) = desc.label {
|
||||
descriptor.set_label(label);
|
||||
}
|
||||
let raw = self.shared.device.lock().new_sampler(&descriptor);
|
||||
|
||||
Ok(super::Sampler { raw })
|
||||
@ -350,6 +357,8 @@ impl crate::Device<super::Api> for super::Device {
|
||||
raw_primitive_type: mtl::MTLPrimitiveType::Point,
|
||||
index_state: None,
|
||||
raw_wg_size: mtl::MTLSize::new(0, 0, 0),
|
||||
max_buffers_per_stage: self.shared.private_caps.max_buffers_per_stage,
|
||||
disabilities: self.shared.disabilities.clone(),
|
||||
})
|
||||
}
|
||||
unsafe fn destroy_command_buffer(&self, _cmd_buf: super::CommandBuffer) {}
|
||||
@ -807,6 +816,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
naga::ShaderStage::Compute,
|
||||
)?;
|
||||
descriptor.set_compute_function(Some(&cs.function));
|
||||
|
||||
if let Some(name) = desc.label {
|
||||
descriptor.set_label(name);
|
||||
}
|
||||
@ -861,7 +871,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
|
||||
unsafe fn create_fence(&self) -> DeviceResult<super::Fence> {
|
||||
Ok(super::Fence {
|
||||
completed_value: atomic::AtomicU64::new(0),
|
||||
completed_value: Arc::new(atomic::AtomicU64::new(0)),
|
||||
pending_command_buffers: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
@ -212,6 +212,9 @@ struct AdapterShared {
|
||||
settings: Settings,
|
||||
}
|
||||
|
||||
unsafe impl Send for AdapterShared {}
|
||||
unsafe impl Sync for AdapterShared {}
|
||||
|
||||
impl AdapterShared {
|
||||
fn new(device: mtl::Device) -> Self {
|
||||
let private_caps = PrivateCapabilities::new(&device);
|
||||
@ -243,7 +246,9 @@ pub struct Adapter {
|
||||
shared: Arc<AdapterShared>,
|
||||
}
|
||||
|
||||
pub struct Queue {}
|
||||
pub struct Queue {
|
||||
shared: Arc<AdapterShared>,
|
||||
}
|
||||
|
||||
pub struct Device {
|
||||
shared: Arc<AdapterShared>,
|
||||
@ -260,6 +265,9 @@ pub struct Surface {
|
||||
pub present_with_transaction: bool,
|
||||
}
|
||||
|
||||
unsafe impl Send for Surface {}
|
||||
unsafe impl Sync for Surface {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SurfaceTexture {
|
||||
texture: Texture,
|
||||
@ -280,15 +288,58 @@ impl crate::Queue<Api> for Queue {
|
||||
unsafe fn submit<I>(
|
||||
&mut self,
|
||||
command_buffers: I,
|
||||
signal_fence: Option<(&Fence, crate::FenceValue)>,
|
||||
) -> Result<(), crate::DeviceError> {
|
||||
signal_fence: Option<(&mut Fence, crate::FenceValue)>,
|
||||
) -> Result<(), crate::DeviceError>
|
||||
where
|
||||
I: Iterator<Item = CommandBuffer>,
|
||||
{
|
||||
objc::rc::autoreleasepool(|| {
|
||||
for cmd_buffer in command_buffers {
|
||||
cmd_buffer.raw.commit();
|
||||
}
|
||||
|
||||
//TODO: add the handler to the last command buffer in the list
|
||||
// instead of committing an extra one
|
||||
if let Some((fence, value)) = signal_fence {
|
||||
let completed_value = Arc::clone(&fence.completed_value);
|
||||
let block = block::ConcreteBlock::new(move |_cmd_buf| {
|
||||
completed_value.store(value, atomic::Ordering::Release);
|
||||
})
|
||||
.copy();
|
||||
|
||||
let raw = self.shared.create_command_buffer();
|
||||
raw.set_label("_Signal");
|
||||
raw.add_completed_handler(&block);
|
||||
raw.commit();
|
||||
|
||||
fence.update();
|
||||
fence.pending_command_buffers.push((value, raw.to_owned()));
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
unsafe fn present(
|
||||
&mut self,
|
||||
surface: &mut Surface,
|
||||
_surface: &mut Surface,
|
||||
texture: SurfaceTexture,
|
||||
) -> Result<(), crate::SurfaceError> {
|
||||
let queue = self.shared.queue.lock();
|
||||
objc::rc::autoreleasepool(|| {
|
||||
let command_buffer = queue.new_command_buffer();
|
||||
command_buffer.set_label("_Present");
|
||||
|
||||
// https://developer.apple.com/documentation/quartzcore/cametallayer/1478157-presentswithtransaction?language=objc
|
||||
if !texture.present_with_transaction {
|
||||
command_buffer.present_drawable(&texture.drawable);
|
||||
}
|
||||
|
||||
command_buffer.commit();
|
||||
|
||||
if texture.present_with_transaction {
|
||||
command_buffer.wait_until_scheduled();
|
||||
texture.drawable.present();
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -520,6 +571,9 @@ pub struct RenderPipeline {
|
||||
depth_stencil: Option<(mtl::DepthStencilState, wgt::DepthBiasState)>,
|
||||
}
|
||||
|
||||
unsafe impl Send for RenderPipeline {}
|
||||
unsafe impl Sync for RenderPipeline {}
|
||||
|
||||
#[allow(dead_code)] // silence xx_lib and xx_info warnings
|
||||
pub struct ComputePipeline {
|
||||
raw: mtl::ComputePipelineState,
|
||||
@ -528,6 +582,9 @@ pub struct ComputePipeline {
|
||||
work_group_size: mtl::MTLSize,
|
||||
}
|
||||
|
||||
unsafe impl Send for ComputePipeline {}
|
||||
unsafe impl Sync for ComputePipeline {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct QuerySet {
|
||||
raw_buffer: mtl::Buffer,
|
||||
@ -539,13 +596,31 @@ unsafe impl Sync for QuerySet {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Fence {
|
||||
completed_value: atomic::AtomicU64,
|
||||
completed_value: Arc<atomic::AtomicU64>,
|
||||
pending_command_buffers: Vec<(crate::FenceValue, mtl::CommandBuffer)>,
|
||||
}
|
||||
|
||||
unsafe impl Send for Fence {}
|
||||
unsafe impl Sync for Fence {}
|
||||
|
||||
impl Fence {
|
||||
fn get_latest(&self) -> crate::FenceValue {
|
||||
let mut max_value = self.completed_value.load(atomic::Ordering::Acquire);
|
||||
for &(value, ref cmd_buf) in self.pending_command_buffers.iter() {
|
||||
if cmd_buf.status() == mtl::MTLCommandBufferStatus::Completed {
|
||||
max_value = value;
|
||||
}
|
||||
}
|
||||
max_value
|
||||
}
|
||||
|
||||
fn update(&mut self) {
|
||||
let latest = self.get_latest();
|
||||
self.pending_command_buffers
|
||||
.retain(|&(value, _)| value > latest);
|
||||
}
|
||||
}
|
||||
|
||||
struct IndexState {
|
||||
buffer_ptr: BufferPtr,
|
||||
offset: wgt::BufferAddress,
|
||||
@ -561,4 +636,9 @@ pub struct CommandBuffer {
|
||||
raw_primitive_type: mtl::MTLPrimitiveType,
|
||||
index_state: Option<IndexState>,
|
||||
raw_wg_size: mtl::MTLSize,
|
||||
max_buffers_per_stage: u32,
|
||||
disabilities: PrivateDisabilities,
|
||||
}
|
||||
|
||||
unsafe impl Send for CommandBuffer {}
|
||||
unsafe impl Sync for CommandBuffer {}
|
||||
|
@ -31,27 +31,17 @@ impl framework::Example for Example {
|
||||
/// constructs initial instance of Example struct
|
||||
fn init(
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
adapter: &wgpu::Adapter,
|
||||
_adapter: &wgpu::Adapter,
|
||||
device: &wgpu::Device,
|
||||
_queue: &wgpu::Queue,
|
||||
) -> Self {
|
||||
// load and compile the shader
|
||||
let mut flags = wgpu::ShaderFlags::VALIDATION;
|
||||
match adapter.get_info().backend {
|
||||
wgt::Backend::Vulkan | wgt::Backend::Metal | wgt::Backend::Gl => {
|
||||
flags |= wgpu::ShaderFlags::EXPERIMENTAL_TRANSLATION;
|
||||
}
|
||||
_ => {} //TODO
|
||||
}
|
||||
let compute_shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: None,
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("compute.wgsl"))),
|
||||
flags,
|
||||
});
|
||||
let draw_shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: None,
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("draw.wgsl"))),
|
||||
flags,
|
||||
});
|
||||
|
||||
// buffer for simulation parameters uniform
|
||||
|
@ -94,11 +94,7 @@ async fn create_red_image_with_dimensions(
|
||||
|
||||
// Copy the data from the texture to the buffer
|
||||
encoder.copy_texture_to_buffer(
|
||||
wgpu::ImageCopyTexture {
|
||||
texture: &texture,
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d::ZERO,
|
||||
},
|
||||
texture.as_image_copy(),
|
||||
wgpu::ImageCopyBuffer {
|
||||
buffer: &output_buffer,
|
||||
layout: wgpu::ImageDataLayout {
|
||||
|
@ -90,7 +90,6 @@ impl framework::Example for Example {
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!(
|
||||
"triangle_and_lines.wgsl"
|
||||
))),
|
||||
flags: wgpu::ShaderFlags::all(),
|
||||
});
|
||||
|
||||
let pipeline_triangle_conservative =
|
||||
@ -200,7 +199,6 @@ impl framework::Example for Example {
|
||||
let shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: None,
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("upscale.wgsl"))),
|
||||
flags: wgpu::ShaderFlags::all(),
|
||||
});
|
||||
(
|
||||
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
|
@ -113,7 +113,7 @@ impl framework::Example for Example {
|
||||
|
||||
fn init(
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
adapter: &wgpu::Adapter,
|
||||
_adapter: &wgpu::Adapter,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
) -> Self {
|
||||
@ -184,11 +184,7 @@ impl framework::Example for Example {
|
||||
});
|
||||
let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
queue.write_texture(
|
||||
wgpu::ImageCopyTexture {
|
||||
texture: &texture,
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d::ZERO,
|
||||
},
|
||||
texture.as_image_copy(),
|
||||
&texels,
|
||||
wgpu::ImageDataLayout {
|
||||
offset: 0,
|
||||
@ -223,17 +219,9 @@ impl framework::Example for Example {
|
||||
label: None,
|
||||
});
|
||||
|
||||
let mut flags = wgpu::ShaderFlags::VALIDATION;
|
||||
match adapter.get_info().backend {
|
||||
wgpu::Backend::Metal | wgpu::Backend::Vulkan | wgpu::Backend::Gl => {
|
||||
flags |= wgpu::ShaderFlags::EXPERIMENTAL_TRANSLATION
|
||||
}
|
||||
_ => (), //TODO
|
||||
}
|
||||
let shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: None,
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
|
||||
flags,
|
||||
});
|
||||
|
||||
let vertex_buffers = [wgpu::VertexBufferLayout {
|
||||
|
@ -64,7 +64,6 @@ async fn execute_gpu(numbers: &[u32]) -> Option<Vec<u32>> {
|
||||
let cs_module = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: None,
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
|
||||
flags: wgpu::ShaderFlags::all(),
|
||||
});
|
||||
|
||||
// Gets the size in bytes of the buffer.
|
||||
|
@ -35,7 +35,6 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
|
||||
let shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: None,
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
|
||||
flags: wgpu::ShaderFlags::all(),
|
||||
});
|
||||
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
|
@ -77,12 +77,10 @@ impl Example {
|
||||
texture: &wgpu::Texture,
|
||||
query_sets: &Option<QuerySets>,
|
||||
mip_count: u32,
|
||||
shader_flags: wgpu::ShaderFlags,
|
||||
) {
|
||||
let shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: None,
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("blit.wgsl"))),
|
||||
flags: shader_flags,
|
||||
});
|
||||
|
||||
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
@ -206,7 +204,7 @@ impl framework::Example for Example {
|
||||
|
||||
fn init(
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
adapter: &wgpu::Adapter,
|
||||
_adapter: &wgpu::Adapter,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
) -> Self {
|
||||
@ -249,11 +247,7 @@ impl framework::Example for Example {
|
||||
rows_per_image: None,
|
||||
},
|
||||
},
|
||||
wgpu::ImageCopyTexture {
|
||||
texture: &texture,
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d::ZERO,
|
||||
},
|
||||
texture.as_image_copy(),
|
||||
texture_extent,
|
||||
);
|
||||
|
||||
@ -277,17 +271,9 @@ impl framework::Example for Example {
|
||||
});
|
||||
|
||||
// Create the render pipeline
|
||||
let mut flags = wgpu::ShaderFlags::VALIDATION;
|
||||
match adapter.get_info().backend {
|
||||
wgpu::Backend::Metal | wgpu::Backend::Vulkan => {
|
||||
flags |= wgpu::ShaderFlags::EXPERIMENTAL_TRANSLATION
|
||||
}
|
||||
_ => (), //TODO
|
||||
}
|
||||
let shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: None,
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("draw.wgsl"))),
|
||||
flags,
|
||||
});
|
||||
|
||||
let draw_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
@ -387,7 +373,6 @@ impl framework::Example for Example {
|
||||
&texture,
|
||||
&query_sets,
|
||||
MIP_LEVEL_COUNT,
|
||||
flags,
|
||||
);
|
||||
|
||||
queue.submit(Some(init_encoder.finish()));
|
||||
|
@ -117,24 +117,16 @@ impl Example {
|
||||
impl framework::Example for Example {
|
||||
fn init(
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
adapter: &wgpu::Adapter,
|
||||
_adapter: &wgpu::Adapter,
|
||||
device: &wgpu::Device,
|
||||
_queue: &wgpu::Queue,
|
||||
) -> Self {
|
||||
log::info!("Press left/right arrow keys to change sample_count.");
|
||||
let sample_count = 4;
|
||||
|
||||
let mut flags = wgpu::ShaderFlags::VALIDATION;
|
||||
match adapter.get_info().backend {
|
||||
wgpu::Backend::Metal | wgpu::Backend::Vulkan => {
|
||||
flags |= wgpu::ShaderFlags::EXPERIMENTAL_TRANSLATION
|
||||
}
|
||||
_ => (), //TODO
|
||||
}
|
||||
let shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: None,
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
|
||||
flags,
|
||||
});
|
||||
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
|
@ -215,7 +215,7 @@ impl framework::Example for Example {
|
||||
|
||||
fn init(
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
adapter: &wgpu::Adapter,
|
||||
_adapter: &wgpu::Adapter,
|
||||
device: &wgpu::Device,
|
||||
_queue: &wgpu::Queue,
|
||||
) -> Self {
|
||||
@ -440,17 +440,9 @@ impl framework::Example for Example {
|
||||
attributes: &vertex_attr,
|
||||
};
|
||||
|
||||
let mut flags = wgpu::ShaderFlags::VALIDATION;
|
||||
match adapter.get_info().backend {
|
||||
wgpu::Backend::Metal | wgpu::Backend::Vulkan => {
|
||||
flags |= wgpu::ShaderFlags::EXPERIMENTAL_TRANSLATION;
|
||||
}
|
||||
_ => (), //TODO
|
||||
}
|
||||
let shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: None,
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
|
||||
flags,
|
||||
});
|
||||
|
||||
let shadow_pass = {
|
||||
|
@ -103,7 +103,7 @@ impl framework::Example for Skybox {
|
||||
|
||||
fn init(
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
adapter: &wgpu::Adapter,
|
||||
_adapter: &wgpu::Adapter,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
) -> Self {
|
||||
@ -176,17 +176,9 @@ impl framework::Example for Skybox {
|
||||
});
|
||||
|
||||
// Create the render pipeline
|
||||
let mut flags = wgpu::ShaderFlags::VALIDATION;
|
||||
match adapter.get_info().backend {
|
||||
wgpu::Backend::Metal | wgpu::Backend::Vulkan => {
|
||||
flags |= wgpu::ShaderFlags::EXPERIMENTAL_TRANSLATION
|
||||
}
|
||||
_ => (), //TODO
|
||||
}
|
||||
let shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: None,
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
|
||||
flags,
|
||||
});
|
||||
|
||||
let camera = Camera {
|
||||
|
@ -151,11 +151,7 @@ impl framework::Example for Example {
|
||||
let green_texture_view = green_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
|
||||
queue.write_texture(
|
||||
wgpu::ImageCopyTexture {
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d::ZERO,
|
||||
texture: &red_texture,
|
||||
},
|
||||
red_texture.as_image_copy(),
|
||||
&red_texture_data,
|
||||
wgpu::ImageDataLayout {
|
||||
offset: 0,
|
||||
@ -165,11 +161,7 @@ impl framework::Example for Example {
|
||||
wgpu::Extent3d::default(),
|
||||
);
|
||||
queue.write_texture(
|
||||
wgpu::ImageCopyTexture {
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d::ZERO,
|
||||
texture: &green_texture,
|
||||
},
|
||||
green_texture.as_image_copy(),
|
||||
&green_texture_data,
|
||||
wgpu::ImageDataLayout {
|
||||
offset: 0,
|
||||
|
@ -263,7 +263,7 @@ impl Example {
|
||||
impl framework::Example for Example {
|
||||
fn init(
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
adapter: &wgpu::Adapter,
|
||||
_adapter: &wgpu::Adapter,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
) -> Self {
|
||||
@ -486,22 +486,13 @@ impl framework::Example for Example {
|
||||
});
|
||||
|
||||
// Upload/compile them to GPU code.
|
||||
let mut flags = wgpu::ShaderFlags::VALIDATION;
|
||||
match adapter.get_info().backend {
|
||||
wgpu::Backend::Metal | wgpu::Backend::Vulkan => {
|
||||
flags |= wgpu::ShaderFlags::EXPERIMENTAL_TRANSLATION
|
||||
}
|
||||
_ => (), //TODO
|
||||
}
|
||||
let terrain_module = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: Some("terrain"),
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("terrain.wgsl"))),
|
||||
flags,
|
||||
});
|
||||
let water_module = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||
label: Some("water"),
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("water.wgsl"))),
|
||||
flags,
|
||||
});
|
||||
|
||||
// Create the render pipelines. These describe how the data will flow through the GPU, and what
|
||||
|
@ -52,7 +52,6 @@ macro_rules! include_spirv {
|
||||
$crate::ShaderModuleDescriptor {
|
||||
label: Some($($token)*),
|
||||
source: $crate::util::make_spirv(include_bytes!($($token)*)),
|
||||
flags: $crate::ShaderFlags::VALIDATION,
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -67,7 +66,6 @@ macro_rules! include_wgsl {
|
||||
$crate::ShaderModuleDescriptor {
|
||||
label: Some($($token)*),
|
||||
source: $crate::ShaderSource::Wgsl(include_str!($($token)*).into()),
|
||||
flags: $crate::ShaderFlags::all(),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user