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