From 43a97878ce14b72f0981164f87f2e35e14151312 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:22:09 +0200 Subject: Adding upstream version 110.0.1. Signed-off-by: Daniel Baumann --- third_party/rust/metal/src/sync.rs | 177 +++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 third_party/rust/metal/src/sync.rs (limited to 'third_party/rust/metal/src/sync.rs') diff --git a/third_party/rust/metal/src/sync.rs b/third_party/rust/metal/src/sync.rs new file mode 100644 index 0000000000..e4b3d8aa67 --- /dev/null +++ b/third_party/rust/metal/src/sync.rs @@ -0,0 +1,177 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; +use block::{Block, RcBlock}; +use std::mem; + +#[cfg(feature = "dispatch_queue")] +use dispatch; + +type MTLSharedEventNotificationBlock<'a> = RcBlock<(&'a SharedEventRef, u64), ()>; + +pub enum MTLEvent {} + +foreign_obj_type! { + type CType = MTLEvent; + pub struct Event; + pub struct EventRef; +} + +impl EventRef { + pub fn device(&self) -> &DeviceRef { + unsafe { msg_send![self, device] } + } +} + +pub enum MTLSharedEvent {} + +foreign_obj_type! { + type CType = MTLSharedEvent; + pub struct SharedEvent; + pub struct SharedEventRef; + type ParentType = EventRef; +} + +impl SharedEventRef { + pub fn signaled_value(&self) -> u64 { + unsafe { msg_send![self, signaledValue] } + } + + pub fn set_signaled_value(&self, new_value: u64) { + unsafe { msg_send![self, setSignaledValue: new_value] } + } + + /// Schedules a notification handler to be called after the shareable event’s signal value + /// equals or exceeds a given value. + pub fn notify( + &self, + listener: &SharedEventListenerRef, + value: u64, + block: MTLSharedEventNotificationBlock, + ) { + unsafe { + // If the block doesn't have a signature, this segfaults. + // Taken from https://github.com/servo/pathfinder/blob/e858c8dc1d8ff02a5b603e21e09a64d6b3e11327/metal/src/lib.rs#L2327 + let block = mem::transmute::< + MTLSharedEventNotificationBlock, + *mut BlockBase<(&SharedEventRef, u64), ()>, + >(block); + (*block).flags |= BLOCK_HAS_SIGNATURE | BLOCK_HAS_COPY_DISPOSE; + (*block).extra = &BLOCK_EXTRA; + let () = msg_send![self, notifyListener:listener atValue:value block:block]; + mem::forget(block); + } + + extern "C" fn dtor(_: *mut BlockBase<(&SharedEventRef, u64), ()>) {} + + const SIGNATURE: &[u8] = b"v16@?0Q8\0"; + const SIGNATURE_PTR: *const i8 = &SIGNATURE[0] as *const u8 as *const i8; + static mut BLOCK_EXTRA: BlockExtra<(&SharedEventRef, u64), ()> = BlockExtra { + unknown0: 0 as *mut i32, + unknown1: 0 as *mut i32, + unknown2: 0 as *mut i32, + dtor, + signature: &SIGNATURE_PTR, + }; + } +} + +pub enum MTLSharedEventListener {} + +foreign_obj_type! { + type CType = MTLSharedEventListener; + pub struct SharedEventListener; + pub struct SharedEventListenerRef; +} + +impl SharedEventListener { + pub unsafe fn from_queue_handle(queue: dispatch_queue_t) -> Self { + let listener: SharedEventListener = msg_send![class!(MTLSharedEventListener), alloc]; + let ptr: *mut Object = msg_send![listener.as_ref(), initWithDispatchQueue: queue]; + if ptr.is_null() { + panic!("[MTLSharedEventListener alloc] initWithDispatchQueue failed"); + } + listener + } + + #[cfg(feature = "dispatch")] + pub fn from_queue(queue: &dispatch::Queue) -> Self { + unsafe { + let raw_queue = std::mem::transmute::<&dispatch::Queue, *const dispatch_queue_t>(queue); + Self::from_queue_handle(*raw_queue) + } + } +} + +pub enum MTLFence {} + +foreign_obj_type! { + type CType = MTLFence; + pub struct Fence; + pub struct FenceRef; +} + +impl FenceRef { + pub fn device(&self) -> &DeviceRef { + unsafe { msg_send![self, device] } + } + + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn set_label(&self, label: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(label); + let () = msg_send![self, setLabel: nslabel]; + } + } +} + +bitflags! { + /// The render stages at which a synchronization command is triggered. + /// + /// Render stages provide finer control for specifying when synchronization must occur, + /// allowing for vertex and fragment processing to overlap in execution. + /// + /// See + pub struct MTLRenderStages: NSUInteger { + /// The vertex rendering stage. + const Vertex = 1 << 0; + /// The fragment rendering stage. + const Fragment = 1 << 1; + /// The tile rendering stage. + const Tile = 1 << 2; + } +} + +const BLOCK_HAS_COPY_DISPOSE: i32 = 0x02000000; +const BLOCK_HAS_SIGNATURE: i32 = 0x40000000; + +#[repr(C)] +struct BlockBase { + isa: *const std::ffi::c_void, // 0x00 + flags: i32, // 0x08 + _reserved: i32, // 0x0c + invoke: unsafe extern "C" fn(*mut Block, ...) -> R, // 0x10 + extra: *const BlockExtra, // 0x18 +} + +type BlockExtraDtor = extern "C" fn(*mut BlockBase); + +#[repr(C)] +struct BlockExtra { + unknown0: *mut i32, // 0x00 + unknown1: *mut i32, // 0x08 + unknown2: *mut i32, // 0x10 + dtor: BlockExtraDtor, // 0x18 + signature: *const *const i8, // 0x20 +} -- cgit v1.2.3