Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  suballocation.rs

  Sprache: Rust
 

use gpu_allocator::{d3d12::AllocationCreateDesc, MemoryLocation};
use parking_lot::Mutex;
use windows::Win32::Graphics::Direct3D12;

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

#[derive(Debug)]
pub(cratestruct GpuAllocatorWrapper {
    pub(crate) allocator: gpu_allocator::d3d12::Allocator,
}

#[derive(Debug)]
pub(cratestruct AllocationWrapper {
    pub(crate) allocation: gpu_allocator::d3d12::Allocation,
}

pub(cratefn create_allocator_wrapper(
    raw: &Direct3D12::ID3D12Device,
    memory_hints: &wgt::MemoryHints,
) -> Result<Mutex<GpuAllocatorWrapper>, crate::DeviceError> {
    // TODO: the allocator's configuration should take hardware capability into
    // account.
    let mb = 1024 * 1024;
    let allocation_sizes = match memory_hints {
        wgt::MemoryHints::Performance => gpu_allocator::AllocationSizes::default(),
        wgt::MemoryHints::MemoryUsage => gpu_allocator::AllocationSizes::new(8 * mb, 4 * mb),
        wgt::MemoryHints::Manual {
            suballocated_device_memory_block_size,
        } => {
            // TODO: Would it be useful to expose the host size in memory hints
            // instead of always using half of the device size?
            let device_size = suballocated_device_memory_block_size.start;
            let host_size = device_size / 2;
            gpu_allocator::AllocationSizes::new(device_size, host_size)
        }
    };

    match gpu_allocator::d3d12::Allocator::new(&gpu_allocator::d3d12::AllocatorCreateDesc {
        device: gpu_allocator::d3d12::ID3D12DeviceVersion::Device(raw.clone()),
        debug_settings: Default::default(),
        allocation_sizes,
    }) {
        Ok(allocator) => Ok(Mutex::new(GpuAllocatorWrapper { allocator })),
        Err(e) => {
            log::error!("Failed to create d3d12 allocator, error: {}", e);
            Err(e)?
        }
    }
}

pub(cratefn create_buffer_resource(
    device: &crate::dx12::Device,
    desc: &crate::BufferDescriptor,
    raw_desc: Direct3D12::D3D12_RESOURCE_DESC,
) -> Result<(Direct3D12::ID3D12Resource, Option<AllocationWrapper>), crate::DeviceError> {
    let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ);
    let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE);

    // Workaround for Intel Xe drivers
    if !device.private_caps.suballocation_supported {
        return create_committed_buffer_resource(device, desc, raw_desc)
            .map(|resource| (resource, None));
    }

    let location = match (is_cpu_read, is_cpu_write) {
        (truetrue) => MemoryLocation::CpuToGpu,
        (truefalse) => MemoryLocation::GpuToCpu,
        (falsetrue) => MemoryLocation::CpuToGpu,
        (falsefalse) => MemoryLocation::GpuOnly,
    };

    let name = desc.label.unwrap_or("Unlabeled buffer");

    let mut allocator = device.mem_allocator.lock();

    let allocation_desc = AllocationCreateDesc::from_d3d12_resource_desc(
        allocator.allocator.device(),
        &raw_desc,
        name,
        location,
    );
    let allocation = allocator.allocator.allocate(&allocation_desc)?;
    let mut resource = None;

    unsafe {
        device.raw.CreatePlacedResource(
            allocation.heap(),
            allocation.offset(),
            &raw_desc,
            Direct3D12::D3D12_RESOURCE_STATE_COMMON,
            None,
            &mut resource,
        )
    }
    .into_device_result("Placed buffer creation")?;

    let resource = resource.ok_or(crate::DeviceError::Unexpected)?;

    device
        .counters
        .buffer_memory
        .add(allocation.size() as isize);

    Ok((resource, Some(AllocationWrapper { allocation })))
}

pub(cratefn create_texture_resource(
    device: &crate::dx12::Device,
    desc: &crate::TextureDescriptor,
    raw_desc: Direct3D12::D3D12_RESOURCE_DESC,
) -> Result<(Direct3D12::ID3D12Resource, Option<AllocationWrapper>), crate::DeviceError> {
    // Workaround for Intel Xe drivers
    if !device.private_caps.suballocation_supported {
        return create_committed_texture_resource(device, desc, raw_desc)
            .map(|resource| (resource, None));
    }

    let location = MemoryLocation::GpuOnly;

    let name = desc.label.unwrap_or("Unlabeled texture");

    let mut allocator = device.mem_allocator.lock();
    let allocation_desc = AllocationCreateDesc::from_d3d12_resource_desc(
        allocator.allocator.device(),
        &raw_desc,
        name,
        location,
    );
    let allocation = allocator.allocator.allocate(&allocation_desc)?;
    let mut resource = None;

    unsafe {
        device.raw.CreatePlacedResource(
            allocation.heap(),
            allocation.offset(),
            &raw_desc,
            Direct3D12::D3D12_RESOURCE_STATE_COMMON,
            None, // clear value
            &mut resource,
        )
    }
    .into_device_result("Placed texture creation")?;

    let resource = resource.ok_or(crate::DeviceError::Unexpected)?;

    device
        .counters
        .texture_memory
        .add(allocation.size() as isize);

    Ok((resource, Some(AllocationWrapper { allocation })))
}

pub(cratefn free_buffer_allocation(
    device: &crate::dx12::Device,
    allocation: AllocationWrapper,
    allocator: &Mutex<GpuAllocatorWrapper>,
) {
    device
        .counters
        .buffer_memory
        .sub(allocation.allocation.size() as isize);
    match allocator.lock().allocator.free(allocation.allocation) {
        Ok(_) => (),
        // TODO: Don't panic here
        Err(e) => panic!("Failed to destroy dx12 buffer, {e}"),
    };
}

pub(cratefn free_texture_allocation(
    device: &crate::dx12::Device,
    allocation: AllocationWrapper,
    allocator: &Mutex<GpuAllocatorWrapper>,
) {
    device
        .counters
        .texture_memory
        .sub(allocation.allocation.size() as isize);
    match allocator.lock().allocator.free(allocation.allocation) {
        Ok(_) => (),
        // TODO: Don't panic here
        Err(e) => panic!("Failed to destroy dx12 texture, {e}"),
    };
}

impl From<gpu_allocator::AllocationError> for crate::DeviceError {
    fn from(result: gpu_allocator::AllocationError) -> Self {
        match result {
            gpu_allocator::AllocationError::OutOfMemory => Self::OutOfMemory,
            gpu_allocator::AllocationError::FailedToMap(e) => {
                log::error!("DX12 gpu-allocator: Failed to map: {}", e);
                Self::Lost
            }
            gpu_allocator::AllocationError::NoCompatibleMemoryTypeFound => {
                log::error!("DX12 gpu-allocator: No Compatible Memory Type Found");
                Self::Lost
            }
            gpu_allocator::AllocationError::InvalidAllocationCreateDesc => {
                log::error!("DX12 gpu-allocator: Invalid Allocation Creation Description");
                Self::Lost
            }
            gpu_allocator::AllocationError::InvalidAllocatorCreateDesc(e) => {
                log::error!(
                    "DX12 gpu-allocator: Invalid Allocator Creation Description: {}",
                    e
                );
                Self::Lost
            }

            gpu_allocator::AllocationError::Internal(e) => {
                log::error!("DX12 gpu-allocator: Internal Error: {}", e);
                Self::Lost
            }
            gpu_allocator::AllocationError::BarrierLayoutNeedsDevice10
            | gpu_allocator::AllocationError::CastableFormatsRequiresEnhancedBarriers
            | gpu_allocator::AllocationError::CastableFormatsRequiresAtLeastDevice12 => {
                unreachable!()
            }
        }
    }
}

pub(cratefn create_committed_buffer_resource(
    device: &crate::dx12::Device,
    desc: &crate::BufferDescriptor,
    raw_desc: Direct3D12::D3D12_RESOURCE_DESC,
) -> Result<Direct3D12::ID3D12Resource, crate::DeviceError> {
    let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ);
    let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE);

    let heap_properties = Direct3D12::D3D12_HEAP_PROPERTIES {
        Type: Direct3D12::D3D12_HEAP_TYPE_CUSTOM,
        CPUPageProperty: if is_cpu_read {
            Direct3D12::D3D12_CPU_PAGE_PROPERTY_WRITE_BACK
        } else if is_cpu_write {
            Direct3D12::D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE
        } else {
            Direct3D12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE
        },
        MemoryPoolPreference: match device.private_caps.memory_architecture {
            crate::dx12::MemoryArchitecture::NonUnified if !is_cpu_read && !is_cpu_write => {
                Direct3D12::D3D12_MEMORY_POOL_L1
            }
            _ => Direct3D12::D3D12_MEMORY_POOL_L0,
        },
        CreationNodeMask: 0,
        VisibleNodeMask: 0,
    };

    let mut resource = None;

    unsafe {
        device.raw.CreateCommittedResource(
            &heap_properties,
            if device.private_caps.heap_create_not_zeroed {
                Direct3D12::D3D12_HEAP_FLAG_CREATE_NOT_ZEROED
            } else {
                Direct3D12::D3D12_HEAP_FLAG_NONE
            },
            &raw_desc,
            Direct3D12::D3D12_RESOURCE_STATE_COMMON,
            None,
            &mut resource,
        )
    }
    .into_device_result("Committed buffer creation")?;

    resource.ok_or(crate::DeviceError::Unexpected)
}

pub(cratefn create_committed_texture_resource(
    device: &crate::dx12::Device,
    _desc: &crate::TextureDescriptor,
    raw_desc: Direct3D12::D3D12_RESOURCE_DESC,
) -> Result<Direct3D12::ID3D12Resource, crate::DeviceError> {
    let heap_properties = Direct3D12::D3D12_HEAP_PROPERTIES {
        Type: Direct3D12::D3D12_HEAP_TYPE_CUSTOM,
        CPUPageProperty: Direct3D12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE,
        MemoryPoolPreference: match device.private_caps.memory_architecture {
            crate::dx12::MemoryArchitecture::NonUnified => Direct3D12::D3D12_MEMORY_POOL_L1,
            crate::dx12::MemoryArchitecture::Unified { .. } => Direct3D12::D3D12_MEMORY_POOL_L0,
        },
        CreationNodeMask: 0,
        VisibleNodeMask: 0,
    };

    let mut resource = None;

    unsafe {
        device.raw.CreateCommittedResource(
            &heap_properties,
            if device.private_caps.heap_create_not_zeroed {
                Direct3D12::D3D12_HEAP_FLAG_CREATE_NOT_ZEROED
            } else {
                Direct3D12::D3D12_HEAP_FLAG_NONE
            },
            &raw_desc,
            Direct3D12::D3D12_RESOURCE_STATE_COMMON,
            None, // clear value
            &mut resource,
        )
    }
    .into_device_result("Committed texture creation")?;

    resource.ok_or(crate::DeviceError::Unexpected)
}

Messung V0.5 in Prozent
C=97 H=95 G=95

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet am  2026-06-22) ¤

*© 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik