mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 00:04:15 +00:00
Add DeviceAddress
, handle pointers as SPIR-V struct members (#2351)
* Add `DeviceAddress`, handle pointers as SPIR-V struct members * Add pointers to vulkano-shaders
This commit is contained in:
parent
fb828a6db2
commit
0175bcd2a6
@ -220,6 +220,7 @@ fn is_aligned(offset: usize, alignment: Alignment) -> bool {
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
enum Type {
|
||||
Scalar(TypeScalar),
|
||||
Pointer(TypePointer),
|
||||
Vector(TypeVector),
|
||||
Matrix(TypeMatrix),
|
||||
Array(TypeArray),
|
||||
@ -238,6 +239,7 @@ impl Type {
|
||||
Instruction::TypeFloat { width, .. } => {
|
||||
Type::Scalar(TypeScalar::Float(TypeFloat::new(shader, width)?))
|
||||
}
|
||||
Instruction::TypePointer { .. } => Type::Pointer(TypePointer::new(shader)?),
|
||||
Instruction::TypeVector {
|
||||
component_type,
|
||||
component_count,
|
||||
@ -268,6 +270,7 @@ impl Type {
|
||||
fn size(&self) -> Option<usize> {
|
||||
match self {
|
||||
Self::Scalar(ty) => Some(ty.size()),
|
||||
Self::Pointer(ty) => Some(ty.size()),
|
||||
Self::Vector(ty) => Some(ty.size()),
|
||||
Self::Matrix(ty) => Some(ty.size()),
|
||||
Self::Array(ty) => ty.size(),
|
||||
@ -278,6 +281,7 @@ impl Type {
|
||||
fn scalar_alignment(&self) -> Alignment {
|
||||
match self {
|
||||
Self::Scalar(ty) => ty.alignment(),
|
||||
Self::Pointer(ty) => ty.alignment(),
|
||||
Self::Vector(ty) => ty.component_type.alignment(),
|
||||
Self::Matrix(ty) => ty.component_type.alignment(),
|
||||
Self::Array(ty) => ty.scalar_alignment(),
|
||||
@ -439,6 +443,29 @@ impl ToTokens for TypeFloat {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
struct TypePointer;
|
||||
|
||||
impl TypePointer {
|
||||
fn new(_shader: &Shader) -> Result<Self> {
|
||||
Ok(TypePointer)
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
8
|
||||
}
|
||||
|
||||
fn alignment(&self) -> Alignment {
|
||||
Alignment::A8
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for TypePointer {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
tokens.extend(quote! { ::vulkano::DeviceAddress });
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
struct TypeVector {
|
||||
component_type: TypeScalar,
|
||||
@ -863,6 +890,7 @@ impl ToTokens for Serializer<'_, Type> {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
match &self.0 {
|
||||
Type::Scalar(ty) => ty.to_tokens(tokens),
|
||||
Type::Pointer(ty) => ty.to_tokens(tokens),
|
||||
Type::Vector(ty) => Serializer(ty, self.1).to_tokens(tokens),
|
||||
Type::Matrix(ty) => Serializer(ty, self.1).to_tokens(tokens),
|
||||
Type::Array(ty) => Serializer(ty, self.1).to_tokens(tokens),
|
||||
|
@ -97,8 +97,8 @@ use crate::{
|
||||
format::{Format, FormatFeatures},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::{impl_id_counter, vulkan_bitflags, vulkan_enum},
|
||||
DeviceSize, NonZeroDeviceSize, Packed24_8, Requires, RequiresAllOf, RequiresOneOf, Validated,
|
||||
ValidationError, VulkanError, VulkanObject,
|
||||
DeviceAddress, DeviceSize, NonNullDeviceAddress, Packed24_8, Requires, RequiresAllOf,
|
||||
RequiresOneOf, Validated, ValidationError, VulkanError, VulkanObject,
|
||||
};
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use std::{fmt::Debug, hash::Hash, mem::MaybeUninit, num::NonZeroU64, ptr, sync::Arc};
|
||||
@ -264,7 +264,7 @@ impl AccelerationStructure {
|
||||
///
|
||||
/// The device address of the acceleration structure may be different from the device address
|
||||
/// of the underlying buffer.
|
||||
pub fn device_address(&self) -> NonZeroDeviceSize {
|
||||
pub fn device_address(&self) -> NonNullDeviceAddress {
|
||||
let info_vk = ash::vk::AccelerationStructureDeviceAddressInfoKHR {
|
||||
acceleration_structure: self.handle,
|
||||
..Default::default()
|
||||
@ -277,7 +277,7 @@ impl AccelerationStructure {
|
||||
)
|
||||
};
|
||||
|
||||
NonZeroDeviceSize::new(ptr).unwrap()
|
||||
NonNullDeviceAddress::new(ptr).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1277,7 +1277,7 @@ pub struct AccelerationStructureInstance {
|
||||
/// The device address of the bottom-level acceleration structure in this instance.
|
||||
///
|
||||
/// The default value is 0 (null).
|
||||
pub acceleration_structure_reference: DeviceSize,
|
||||
pub acceleration_structure_reference: DeviceAddress,
|
||||
}
|
||||
|
||||
impl Default for AccelerationStructureInstance {
|
||||
|
@ -93,8 +93,8 @@ use crate::{
|
||||
},
|
||||
range_map::RangeMap,
|
||||
sync::{future::AccessError, AccessConflict, CurrentAccess, Sharing},
|
||||
DeviceSize, NonZeroDeviceSize, Requires, RequiresAllOf, RequiresOneOf, Validated,
|
||||
ValidationError, Version, VulkanError, VulkanObject,
|
||||
DeviceSize, NonNullDeviceAddress, NonZeroDeviceSize, Requires, RequiresAllOf, RequiresOneOf,
|
||||
Validated, ValidationError, Version, VulkanError, VulkanObject,
|
||||
};
|
||||
use parking_lot::{Mutex, MutexGuard};
|
||||
use smallvec::SmallVec;
|
||||
@ -476,7 +476,7 @@ impl Buffer {
|
||||
|
||||
/// Returns the device address for this buffer.
|
||||
// TODO: Caching?
|
||||
pub fn device_address(&self) -> Result<NonZeroDeviceSize, Box<ValidationError>> {
|
||||
pub fn device_address(&self) -> Result<NonNullDeviceAddress, Box<ValidationError>> {
|
||||
self.validate_device_address()?;
|
||||
|
||||
unsafe { Ok(self.device_address_unchecked()) }
|
||||
@ -508,7 +508,7 @@ impl Buffer {
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||
pub unsafe fn device_address_unchecked(&self) -> NonZeroDeviceSize {
|
||||
pub unsafe fn device_address_unchecked(&self) -> NonNullDeviceAddress {
|
||||
let device = self.device();
|
||||
|
||||
let info_vk = ash::vk::BufferDeviceAddressInfo {
|
||||
@ -528,7 +528,7 @@ impl Buffer {
|
||||
f(device.handle(), &info_vk)
|
||||
};
|
||||
|
||||
NonZeroDeviceSize::new(ptr).unwrap()
|
||||
NonNullDeviceAddress::new(ptr).unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn state(&self) -> MutexGuard<'_, BufferState> {
|
||||
|
@ -19,7 +19,7 @@ use crate::{
|
||||
is_aligned, DeviceAlignment, MappedMemoryRange,
|
||||
},
|
||||
sync::HostAccessError,
|
||||
DeviceSize, NonZeroDeviceSize, ValidationError,
|
||||
DeviceSize, NonNullDeviceAddress, NonZeroDeviceSize, ValidationError,
|
||||
};
|
||||
use bytemuck::AnyBitPattern;
|
||||
use std::{
|
||||
@ -138,21 +138,21 @@ impl<T: ?Sized> Subbuffer<T> {
|
||||
}
|
||||
|
||||
/// Returns the device address for this subbuffer.
|
||||
pub fn device_address(&self) -> Result<NonZeroDeviceSize, Box<ValidationError>> {
|
||||
pub fn device_address(&self) -> Result<NonNullDeviceAddress, Box<ValidationError>> {
|
||||
self.buffer().device_address().map(|ptr| {
|
||||
// SAFETY: The original address came from the Vulkan implementation, and allocation
|
||||
// sizes are guaranteed to not exceed `DeviceLayout::MAX_SIZE`, so the offset better be
|
||||
// in range.
|
||||
unsafe { NonZeroDeviceSize::new_unchecked(ptr.get() + self.offset) }
|
||||
unsafe { NonNullDeviceAddress::new_unchecked(ptr.get() + self.offset) }
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||
pub unsafe fn device_address_unchecked(&self) -> NonZeroDeviceSize {
|
||||
pub unsafe fn device_address_unchecked(&self) -> NonNullDeviceAddress {
|
||||
// SAFETY: The original address came from the Vulkan implementation, and allocation
|
||||
// sizes are guaranteed to not exceed `DeviceLayout::MAX_SIZE`, so the offset better be
|
||||
// in range.
|
||||
NonZeroDeviceSize::new_unchecked(
|
||||
NonNullDeviceAddress::new_unchecked(
|
||||
self.buffer().device_address_unchecked().get() + self.offset,
|
||||
)
|
||||
}
|
||||
|
@ -206,6 +206,12 @@ pub use ash::vk::DeviceSize;
|
||||
/// A [`DeviceSize`] that is known not to equal zero.
|
||||
pub type NonZeroDeviceSize = NonZeroU64;
|
||||
|
||||
/// Represents an address (pointer) on a Vulkan device.
|
||||
pub use ash::vk::DeviceAddress;
|
||||
|
||||
/// A [`DeviceAddress`] that is known not to equal zero.
|
||||
pub type NonNullDeviceAddress = NonZeroU64;
|
||||
|
||||
/// Holds 24 bits in the least significant bits of memory,
|
||||
/// and 8 bytes in the most significant bits of that memory,
|
||||
/// occupying a single [`u32`] in total.
|
||||
|
Loading…
Reference in New Issue
Block a user