products/Sources/formale Sprachen/C/Firefox/third_party/rust/wgpu-hal/src/metal/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 28 kB image not shown  

SSL descriptor.rs

  Sprache: Rust
 

use std::fmt;

use bit_set::BitSet;
use parking_lot::Mutex;
use range_alloc::RangeAllocator;
use windows::Win32::Graphics::Direct3D12;

use crate::auxil::dxgi::result::HResult as _;

const HEAP_SIZE_FIXED: usize = 64;

#[derive(Copy, Clone)]
pub(superstruct DualHandle {
    cpu: Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE,
    pub gpu: Direct3D12::D3D12_GPU_DESCRIPTOR_HANDLE,
    /// How large the block allocated to this handle is.
    count: u64,
}

impl fmt::Debug for DualHandle {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("DualHandle")
            .field("cpu", &self.cpu.ptr)
            .field("gpu", &self.gpu.ptr)
            .field("count", &self.count)
            .finish()
    }
}

type DescriptorIndex = u64;

pub(superstruct GeneralHeap {
    pub raw: Direct3D12::ID3D12DescriptorHeap,
    ty: Direct3D12::D3D12_DESCRIPTOR_HEAP_TYPE,
    handle_size: u64,
    total_handles: u64,
    start: DualHandle,
    ranges: Mutex<RangeAllocator<DescriptorIndex>>,
}

impl GeneralHeap {
    pub(superfn new(
        device: &Direct3D12::ID3D12Device,
        ty: Direct3D12::D3D12_DESCRIPTOR_HEAP_TYPE,
        total_handles: u64,
    ) -> Result<Selfcrate::DeviceError> {
        let raw = {
            profiling::scope!("ID3D12Device::CreateDescriptorHeap");
            let desc = Direct3D12::D3D12_DESCRIPTOR_HEAP_DESC {
                Type: ty,
                NumDescriptors: total_handles as u32,
                Flags: Direct3D12::D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
                NodeMask: 0,
            };
            unsafe { device.CreateDescriptorHeap::<Direct3D12::ID3D12DescriptorHeap>(&desc) }
                .into_device_result("Descriptor heap creation")?
        };

        let start = DualHandle {
            cpu: unsafe { raw.GetCPUDescriptorHandleForHeapStart() },
            gpu: unsafe { raw.GetGPUDescriptorHandleForHeapStart() },
            count: 0,
        };

        Ok(Self {
            raw,
            ty,
            handle_size: unsafe { device.GetDescriptorHandleIncrementSize(ty) } as u64,
            total_handles,
            start,
            ranges: Mutex::new(RangeAllocator::new(0..total_handles)),
        })
    }

    pub(superfn at(&self, index: DescriptorIndex, count: u64) -> DualHandle {
        assert!(index < self.total_handles);
        DualHandle {
            cpu: self.cpu_descriptor_at(index),
            gpu: self.gpu_descriptor_at(index),
            count,
        }
    }

    fn cpu_descriptor_at(&self, index: u64) -> Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE {
        Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE {
            ptr: self.start.cpu.ptr + (self.handle_size * index) as usize,
        }
    }

    fn gpu_descriptor_at(&self, index: u64) -> Direct3D12::D3D12_GPU_DESCRIPTOR_HANDLE {
        Direct3D12::D3D12_GPU_DESCRIPTOR_HANDLE {
            ptr: self.start.gpu.ptr + self.handle_size * index,
        }
    }

    pub(superfn allocate_slice(&self, count: u64) -> Result<DescriptorIndex, crate::DeviceError> {
        let range = self.ranges.lock().allocate_range(count).map_err(|err| {
            log::error!("Unable to allocate descriptors: {:?}", err);
            crate::DeviceError::OutOfMemory
        })?;
        Ok(range.start)
    }

    /// Free handles previously given out by this `DescriptorHeapSlice`.
    /// Do not use this with handles not given out by this `DescriptorHeapSlice`.
    pub(cratefn free_slice(&self, handle: DualHandle) {
        let start = (handle.gpu.ptr - self.start.gpu.ptr) / self.handle_size;
        self.ranges.lock().free_range(start..start + handle.count);
    }
}

/// Fixed-size free-list allocator for CPU descriptors.
struct FixedSizeHeap {
    _raw: Direct3D12::ID3D12DescriptorHeap,
    /// Bit flag representation of available handles in the heap.
    ///
    ///  0 - Occupied
    ///  1 - free
    availability: u64,
    handle_size: usize,
    start: Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE,
}

impl FixedSizeHeap {
    fn new(
        device: &Direct3D12::ID3D12Device,
        ty: Direct3D12::D3D12_DESCRIPTOR_HEAP_TYPE,
    ) -> Result<Selfcrate::DeviceError> {
        let desc = Direct3D12::D3D12_DESCRIPTOR_HEAP_DESC {
            Type: ty,
            NumDescriptors: HEAP_SIZE_FIXED as u32,
            Flags: Direct3D12::D3D12_DESCRIPTOR_HEAP_FLAG_NONE,
            NodeMask: 0,
        };
        let heap =
            unsafe { device.CreateDescriptorHeap::<Direct3D12::ID3D12DescriptorHeap>(&desc) }
                .into_device_result("Descriptor heap creation")?;

        Ok(Self {
            handle_size: unsafe { device.GetDescriptorHandleIncrementSize(ty) } as usize,
            availability: !0// all free!
            start: unsafe { heap.GetCPUDescriptorHandleForHeapStart() },
            _raw: heap,
        })
    }

    fn alloc_handle(
        &mut self,
    ) -> Result<Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE, crate::DeviceError> {
        // Find first free slot.
        let slot = self.availability.trailing_zeros() as usize;
        if slot >= HEAP_SIZE_FIXED {
            log::error!("Failed to allocate a handle form a fixed size heap");
            return Err(crate::DeviceError::OutOfMemory);
        }
        // Set the slot as occupied.
        self.availability ^= 1 << slot;

        Ok(Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE {
            ptr: self.start.ptr + self.handle_size * slot,
        })
    }

    fn free_handle(&mut self, handle: Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE) {
        let slot = (handle.ptr - self.start.ptr) / self.handle_size;
        assert!(slot < HEAP_SIZE_FIXED);
        assert_eq!(self.availability & (1 << slot), 0);
        self.availability ^= 1 << slot;
    }

    fn is_full(&self) -> bool {
        self.availability == 0
    }
}

#[derive(Clone, Copy)]
pub(superstruct Handle {
    pub raw: Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE,
    heap_index: usize,
}

impl fmt::Debug for Handle {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Handle")
            .field("ptr", &self.raw.ptr)
            .field("heap_index", &self.heap_index)
            .finish()
    }
}

pub(superstruct CpuPool {
    device: Direct3D12::ID3D12Device,
    ty: Direct3D12::D3D12_DESCRIPTOR_HEAP_TYPE,
    heaps: Vec<FixedSizeHeap>,
    available_heap_indices: BitSet,
}

impl CpuPool {
    pub(superfn new(
        device: Direct3D12::ID3D12Device,
        ty: Direct3D12::D3D12_DESCRIPTOR_HEAP_TYPE,
    ) -> Self {
        Self {
            device,
            ty,
            heaps: Vec::new(),
            available_heap_indices: BitSet::new(),
        }
    }

    pub(superfn alloc_handle(&mut self) -> Result<Handle, crate::DeviceError> {
        let heap_index = self
            .available_heap_indices
            .iter()
            .next()
            .unwrap_or(self.heaps.len());

        // Allocate a new heap
        if heap_index == self.heaps.len() {
            self.heaps.push(FixedSizeHeap::new(&self.device, self.ty)?);
            self.available_heap_indices.insert(heap_index);
        }

        let heap = &mut self.heaps[heap_index];
        let handle = Handle {
            raw: heap.alloc_handle()?,
            heap_index,
        };
        if heap.is_full() {
            self.available_heap_indices.remove(heap_index);
        }

        Ok(handle)
    }

    pub(superfn free_handle(&mut self, handle: Handle) {
        self.heaps[handle.heap_index].free_handle(handle.raw);
        self.available_heap_indices.insert(handle.heap_index);
    }
}

pub(superstruct CpuHeapInner {
    pub _raw: Direct3D12::ID3D12DescriptorHeap,
    pub stage: Vec<Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE>,
}

pub(superstruct CpuHeap {
    pub inner: Mutex<CpuHeapInner>,
    start: Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE,
    handle_size: u32,
    total: u32,
}

unsafe impl Send for CpuHeap {}
unsafe impl Sync for CpuHeap {}

impl CpuHeap {
    pub(superfn new(
        device: &Direct3D12::ID3D12Device,
        ty: Direct3D12::D3D12_DESCRIPTOR_HEAP_TYPE,
        total: u32,
    ) -> Result<Selfcrate::DeviceError> {
        let handle_size = unsafe { device.GetDescriptorHandleIncrementSize(ty) };
        let desc = Direct3D12::D3D12_DESCRIPTOR_HEAP_DESC {
            Type: ty,
            NumDescriptors: total,
            Flags: Direct3D12::D3D12_DESCRIPTOR_HEAP_FLAG_NONE,
            NodeMask: 0,
        };
        let raw = unsafe { device.CreateDescriptorHeap::<Direct3D12::ID3D12DescriptorHeap>(&desc) ;}
            .into_device_result("CPU descriptor heap creation")?;

        let start = unsafe { raw.GetCPUDescriptorHandleForHeapStart() };

        Ok(Self {
            inner: Mutex::new(CpuHeapInner {
                _raw: raw,
                stage: Vec::new(),
            }),
            start,
            handle_size,
            total,
        })
    }

    pub(superfn at(&self, index: u32) -> Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE {
        Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE {
            ptr: self.start.ptr + (self.handle_size * index) as usize,
        }
    }
}

impl fmt::Debug for CpuHeap {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("CpuHeap")
            .field("start", &self.start.ptr)
            .field("handle_size", &self.handle_size)
            .field("total", &self.total)
            .finish()
    }
}

pub(superunsafe fn upload(
    device: &Direct3D12::ID3D12Device,
    src: &CpuHeapInner,
    dst: &GeneralHeap,
    dummy_copy_counts: &[u32],
) -> Result<DualHandle, crate::DeviceError> {
    let count = src.stage.len() as u32;
    let index = dst.allocate_slice(count as u64)?;
    unsafe {
        device.CopyDescriptors(
            1,
            &dst.cpu_descriptor_at(index),
            Some(&count),
            count,
            src.stage.as_ptr(),
            Some(dummy_copy_counts.as_ptr()),
            dst.ty,
        )
    };
    Ok(dst.at(index, count as u64))
}

Messung V0.5 in Prozent
C=97 H=88 G=92

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-06-23) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.