}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
-pub struct Texture(Handle);
+pub struct Image(Handle);
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct Buffer(Handle);
}
#[derive(Clone, Copy, PartialEq, Eq)]
-pub enum TextureDimension {
+pub enum ImageDimension {
Type1d,
Type2d,
Type3d,
#[derive(Clone, Copy, PartialEq, Eq)]
#[allow(non_camel_case_types)]
-pub enum TextureFormat {
+pub enum ImageFormat {
BGRA8_SRGB,
BGRA8_UNORM,
RGBA8_SRGB,
DEPTH_F32,
}
-flags_def!(TextureAspectFlags);
-impl TextureAspectFlags {
+flags_def!(ImageAspectFlags);
+impl ImageAspectFlags {
pub const COLOR: Self = Self(1 << 0);
pub const DEPTH: Self = Self(1 << 1);
pub const STENCIL: Self = Self(1 << 2);
}
-flags_def!(TextureUsageFlags);
-impl TextureUsageFlags {
+flags_def!(ImageUsageFlags);
+impl ImageUsageFlags {
pub const SAMPLED: Self = Self(1 << 0);
pub const STORAGE: Self = Self(1 << 1);
pub const DEPTH_STENCIL: Self = Self(1 << 2);
pub const TRANSFER_DST: Self = Self(1 << 5);
}
-pub struct TextureSubresourceLayers {
- pub aspect: TextureAspectFlags,
+pub struct ImageSubresourceLayers {
+ pub aspect: ImageAspectFlags,
pub mip_level: u32,
pub base_array_layer: u32,
pub array_layer_count: u32,
}
-pub struct TextureSubresourceRange {
- pub aspect: TextureAspectFlags,
+pub struct ImageSubresourceRange {
+ pub aspect: ImageAspectFlags,
pub base_mip_level: u32,
pub mip_level_count: u32,
pub base_array_layer: u32,
pub size: usize,
}
-pub struct TextureDesc {
+pub struct ImageDesc {
pub memory_location: MemoryLocation,
- pub usage: TextureUsageFlags,
- pub dimension: TextureDimension,
- pub format: TextureFormat,
- pub initial_layout: TextureLayout,
+ pub usage: ImageUsageFlags,
+ pub dimension: ImageDimension,
+ pub format: ImageFormat,
+ pub initial_layout: ImageLayout,
pub width: u32,
pub height: u32,
pub depth: u32,
pub mip_levels: u32,
}
-pub struct TextureViewDesc {
- pub texture: Texture,
- pub dimension: TextureDimension,
- pub format: TextureFormat,
- pub subresource_range: TextureSubresourceRange,
+pub struct ImageViewDesc {
+ pub image: Image,
+ pub dimension: ImageDimension,
+ pub format: ImageFormat,
+ pub subresource_range: ImageSubresourceRange,
}
-pub struct BufferTextureCopy {
+pub struct BufferImageCopy {
pub buffer_offset: u64,
pub buffer_row_length: u32,
pub buffer_image_height: u32,
- pub texture_subresource_layers: TextureSubresourceLayers,
- pub texture_offset: Offset3d,
- pub texture_extent: Extent3d,
+ pub image_subresource_layers: ImageSubresourceLayers,
+ pub image_offset: Offset3d,
+ pub image_extent: Extent3d,
}
pub struct ShaderDesc<'a> {
}
pub struct GraphicsPipelineLayout<'a> {
- pub color_attachment_formats: &'a [TextureFormat],
- pub depth_attachment_format: Option<TextureFormat>,
- pub stencil_attachment_format: Option<TextureFormat>,
+ pub color_attachment_formats: &'a [ImageFormat],
+ pub depth_attachment_format: Option<ImageFormat>,
+ pub stencil_attachment_format: Option<ImageFormat>,
}
pub struct GraphicsPipelineDesc<'a> {
}
pub struct RenderingAttachment {
- pub texture: Texture,
+ pub image: Image,
pub load_op: LoadOp,
pub store_op: StoreOp,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BindingType {
Sampler,
- Texture,
+ Image,
UniformBuffer,
StorageBuffer,
DynamicUniformBuffer,
pub enum TypedBind<'a> {
Sampler(&'a [Sampler]),
- Texture(&'a [Texture]),
+ Image(&'a [Image]),
UniformBuffer(&'a [Buffer]),
StorageBuffer(&'a [Buffer]),
}
}
}
-pub enum TextureLayout {
+pub enum ImageLayout {
Optimal,
General,
}
pub next_access: &'a [Access],
}
-pub struct TextureBarrier<'a> {
+pub struct ImageBarrier<'a> {
pub prev_access: &'a [Access],
pub next_access: &'a [Access],
- pub prev_layout: TextureLayout,
- pub next_layout: TextureLayout,
- pub texture: Texture,
- pub subresource_range: TextureSubresourceRange,
+ pub prev_layout: ImageLayout,
+ pub next_layout: ImageLayout,
+ pub image: Image,
+ pub subresource_range: ImageSubresourceRange,
}
thread_token_def!(ThreadToken, GpuConcurrent, 8);
}
pub trait Device {
- fn create_buffer(&self, buffer_desc: &BufferDesc) -> Buffer;
- fn create_texture(&self, texture_desc: &TextureDesc) -> Texture;
- fn create_texture_view(&self, desc: &TextureViewDesc) -> Texture;
+ fn create_buffer(&self, desc: &BufferDesc) -> Buffer;
+ fn create_image(&self, desc: &ImageDesc) -> Image;
+ fn create_image_view(&self, desc: &ImageViewDesc) -> Image;
fn create_sampler(&self, desc: &SamplerDesc) -> Sampler;
fn create_bind_group_layout(&self, desc: &BindGroupLayoutDesc) -> BindGroupLayout;
fn create_graphics_pipeline(&self, desc: &GraphicsPipelineDesc) -> Pipeline;
fn create_compute_pipeline(&self, desc: &ComputePipelineDesc) -> Pipeline;
fn destroy_buffer(&self, frame: &Frame, buffer: Buffer);
- fn destroy_texture(&self, frame: &Frame, texture: Texture);
+ fn destroy_image(&self, frame: &Frame, image: Image);
fn destroy_sampler(&self, frame: &Frame, sampler: Sampler);
fn destroy_bind_group_layout(&self, frame: &Frame, bind_group_layout: BindGroupLayout);
fn destroy_pipeline(&self, frame: &Frame, pipeline: Pipeline);
&self,
frame: &Frame,
window: Window,
- format: TextureFormat,
- ) -> (u32, u32, Texture);
+ format: ImageFormat,
+ ) -> (u32, u32, Image);
fn destroy_window(&self, window: Window);
#[must_use]
&self,
cmd_buffer: &mut CmdBuffer,
global_barrier: Option<&GlobalBarrier>,
- texture_barriers: &[TextureBarrier],
+ image_barriers: &[ImageBarrier],
);
- fn cmd_copy_buffer_to_texture(
+ fn cmd_copy_buffer_to_image(
&self,
cmd_buffer: &mut CmdBuffer,
src_buffer: Buffer,
- dst_texture: Texture,
- dst_texture_layout: TextureLayout,
- copies: &[BufferTextureCopy],
+ dst_image: Image,
+ dst_image_layout: ImageLayout,
+ copies: &[BufferImageCopy],
);
fn cmd_begin_rendering(&self, cmd_buffer: &mut CmdBuffer, desc: &RenderingDesc);
use crate::{
delay_queue::DelayQueue, Access, Bind, BindGroupLayout, BindGroupLayoutDesc, BindingType,
- Buffer, BufferDesc, BufferTextureCopy, BufferUsageFlags, ClearValue, CmdBuffer, CompareOp,
+ Buffer, BufferDesc, BufferImageCopy, BufferUsageFlags, ClearValue, CmdBuffer, CompareOp,
ComputePipelineDesc, CullingMode, Device, Extent2d, Extent3d, Frame, FrontFace, GlobalBarrier,
- GpuConcurrent, GraphicsPipelineDesc, IndexType, LoadOp, MemoryLocation, Offset2d, Offset3d,
+ GpuConcurrent, GraphicsPipelineDesc, Image, ImageAspectFlags, ImageBarrier, ImageDesc,
+ ImageDimension, ImageFormat, ImageLayout, ImageSubresourceLayers, ImageSubresourceRange,
+ ImageUsageFlags, ImageViewDesc, IndexType, LoadOp, MemoryLocation, Offset2d, Offset3d,
Pipeline, PolygonMode, Sampler, SamplerAddressMode, SamplerCompareOp, SamplerDesc,
- SamplerFilter, ShaderStageFlags, StencilOp, StencilOpState, StoreOp, Texture,
- TextureAspectFlags, TextureBarrier, TextureDesc, TextureDimension, TextureFormat,
- TextureLayout, TextureSubresourceLayers, TextureSubresourceRange, TextureUsageFlags,
- TextureViewDesc, ThreadToken, Topology, TypedBind,
+ SamplerFilter, ShaderStageFlags, StencilOp, StencilOpState, StoreOp, ThreadToken, Topology,
+ TypedBind,
};
const NUM_FRAMES: usize = 2;
}
#[must_use]
-fn vulkan_format(format: TextureFormat) -> vk::Format {
+fn vulkan_format(format: ImageFormat) -> vk::Format {
match format {
- TextureFormat::RGBA8_SRGB => vk::Format::R8G8B8A8_SRGB,
- TextureFormat::RGBA8_UNORM => vk::Format::R8G8B8A8_UNORM,
- TextureFormat::BGRA8_SRGB => vk::Format::B8G8R8A8_SRGB,
- TextureFormat::BGRA8_UNORM => vk::Format::B8G8R8A8_UNORM,
- TextureFormat::DEPTH_F32 => vk::Format::D32_SFLOAT,
+ ImageFormat::RGBA8_SRGB => vk::Format::R8G8B8A8_SRGB,
+ ImageFormat::RGBA8_UNORM => vk::Format::R8G8B8A8_UNORM,
+ ImageFormat::BGRA8_SRGB => vk::Format::B8G8R8A8_SRGB,
+ ImageFormat::BGRA8_UNORM => vk::Format::B8G8R8A8_UNORM,
+ ImageFormat::DEPTH_F32 => vk::Format::D32_SFLOAT,
}
}
-fn vulkan_aspect_for_format(format: TextureFormat) -> vk::ImageAspectFlags {
+fn vulkan_aspect_for_format(format: ImageFormat) -> vk::ImageAspectFlags {
match format {
- TextureFormat::BGRA8_SRGB
- | TextureFormat::BGRA8_UNORM
- | TextureFormat::RGBA8_SRGB
- | TextureFormat::RGBA8_UNORM => vk::ImageAspectFlags::COLOR,
- TextureFormat::DEPTH_F32 => vk::ImageAspectFlags::DEPTH,
+ ImageFormat::BGRA8_SRGB
+ | ImageFormat::BGRA8_UNORM
+ | ImageFormat::RGBA8_SRGB
+ | ImageFormat::RGBA8_UNORM => vk::ImageAspectFlags::COLOR,
+ ImageFormat::DEPTH_F32 => vk::ImageAspectFlags::DEPTH,
}
}
-fn vulkan_aspect(aspect: TextureAspectFlags) -> vk::ImageAspectFlags {
+fn vulkan_aspect(aspect: ImageAspectFlags) -> vk::ImageAspectFlags {
let mut aspect_flags = default();
- if aspect.contains(TextureAspectFlags::COLOR) {
+ if aspect.contains(ImageAspectFlags::COLOR) {
aspect_flags |= vk::ImageAspectFlags::COLOR;
}
- if aspect.contains(TextureAspectFlags::DEPTH) {
+ if aspect.contains(ImageAspectFlags::DEPTH) {
aspect_flags |= vk::ImageAspectFlags::DEPTH;
}
- if aspect.contains(TextureAspectFlags::STENCIL) {
+ if aspect.contains(ImageAspectFlags::STENCIL) {
aspect_flags |= vk::ImageAspectFlags::STENCIL;
}
aspect_flags
fn vulkan_descriptor_type(binding_type: BindingType) -> vk::DescriptorType {
match binding_type {
BindingType::Sampler => vk::DescriptorType::Sampler,
- BindingType::Texture => vk::DescriptorType::SampledImage,
+ BindingType::Image => vk::DescriptorType::SampledImage,
BindingType::UniformBuffer => vk::DescriptorType::UniformBuffer,
BindingType::StorageBuffer => vk::DescriptorType::StorageBuffer,
BindingType::DynamicUniformBuffer => vk::DescriptorType::UniformBufferDynamic,
}
#[must_use]
-fn vulkan_image_view_type(
- layer_count: u32,
- texture_dimension: TextureDimension,
-) -> vk::ImageViewType {
- match (layer_count, texture_dimension) {
- (1, TextureDimension::Type1d) => vk::ImageViewType::Type1d,
- (1, TextureDimension::Type2d) => vk::ImageViewType::Type2d,
- (1, TextureDimension::Type3d) => vk::ImageViewType::Type3d,
- (6, TextureDimension::TypeCube) => vk::ImageViewType::TypeCube,
- (_, TextureDimension::Type1d) => vk::ImageViewType::Type1dArray,
- (_, TextureDimension::Type2d) => vk::ImageViewType::Type2dArray,
- (_, TextureDimension::TypeCube) => vk::ImageViewType::TypeCubeArray,
+fn vulkan_image_view_type(layer_count: u32, image_dimension: ImageDimension) -> vk::ImageViewType {
+ match (layer_count, image_dimension) {
+ (1, ImageDimension::Type1d) => vk::ImageViewType::Type1d,
+ (1, ImageDimension::Type2d) => vk::ImageViewType::Type2d,
+ (1, ImageDimension::Type3d) => vk::ImageViewType::Type3d,
+ (6, ImageDimension::TypeCube) => vk::ImageViewType::TypeCube,
+ (_, ImageDimension::Type1d) => vk::ImageViewType::Type1dArray,
+ (_, ImageDimension::Type2d) => vk::ImageViewType::Type2dArray,
+ (_, ImageDimension::TypeCube) => vk::ImageViewType::TypeCubeArray,
_ => panic!("unsupported view type"),
}
}
fn vulkan_subresource_layers(
- subresource_layers: &TextureSubresourceLayers,
+ subresource_layers: &ImageSubresourceLayers,
) -> vk::ImageSubresourceLayers {
vk::ImageSubresourceLayers {
aspect_mask: vulkan_aspect(subresource_layers.aspect),
}
}
-fn vulkan_subresource_range(subresource: &TextureSubresourceRange) -> vk::ImageSubresourceRange {
+fn vulkan_subresource_range(subresource: &ImageSubresourceRange) -> vk::ImageSubresourceRange {
vk::ImageSubresourceRange {
aspect_mask: vulkan_aspect(subresource.aspect),
base_mip_level: subresource.base_mip_level,
}
fn vulkan_image_memory_barrier(
- barrier: &TextureBarrier,
+ barrier: &ImageBarrier,
image: vk::Image,
subresource_range: vk::ImageSubresourceRange,
) -> vk::ImageMemoryBarrier2 {
}
let layout = match barrier.prev_layout {
- TextureLayout::Optimal => info.layout,
- TextureLayout::General => {
+ ImageLayout::Optimal => info.layout,
+ ImageLayout::General => {
if access == Access::PresentRead {
vk::ImageLayout::PresentSrcKhr
} else {
}
let layout = match barrier.next_layout {
- TextureLayout::Optimal => info.layout,
- TextureLayout::General => {
+ ImageLayout::Optimal => info.layout,
+ ImageLayout::General => {
if access == Access::PresentRead {
vk::ImageLayout::PresentSrcKhr
} else {
}
#[derive(Clone)]
-struct VulkanTexture {
+struct VulkanImage {
memory: VulkanMemory,
image: vk::Image,
}
-struct VulkanTextureUnique {
- texture: VulkanTexture,
+struct VulkanImageUnique {
+ image: VulkanImage,
view: vk::ImageView,
}
-struct VulkanTextureShared {
- texture: ManualArc<VulkanTexture>,
+struct VulkanImageShared {
+ image: ManualArc<VulkanImage>,
view: vk::ImageView,
}
-struct VulkanTextureSwapchain {
+struct VulkanImageSwapchain {
window: Window,
image: vk::Image,
view: vk::ImageView,
}
-enum VulkanTextureHolder {
- Unique(VulkanTextureUnique),
- Shared(VulkanTextureShared),
- Swapchain(VulkanTextureSwapchain),
+enum VulkanImageHolder {
+ Unique(VulkanImageUnique),
+ Shared(VulkanImageShared),
+ Swapchain(VulkanImageSwapchain),
}
-impl VulkanTextureHolder {
+impl VulkanImageHolder {
fn image(&self) -> vk::Image {
match self {
- VulkanTextureHolder::Unique(x) => x.texture.image,
- VulkanTextureHolder::Shared(_) => panic!(),
- VulkanTextureHolder::Swapchain(_) => panic!(),
+ VulkanImageHolder::Unique(x) => x.image.image,
+ VulkanImageHolder::Shared(_) => panic!(),
+ VulkanImageHolder::Swapchain(_) => panic!(),
}
}
fn image_view(&self) -> vk::ImageView {
match self {
- VulkanTextureHolder::Unique(x) => x.view,
- VulkanTextureHolder::Shared(x) => x.view,
- VulkanTextureHolder::Swapchain(x) => x.view,
+ VulkanImageHolder::Unique(x) => x.view,
+ VulkanImageHolder::Shared(x) => x.view,
+ VulkanImageHolder::Swapchain(x) => x.view,
}
}
}
height: u32,
suboptimal: bool,
swapchain: vk::SwapchainKHR,
- image_views: Box<[Texture]>,
+ image_views: Box<[Image]>,
},
}
swapchains: Mutex<HashMap<Window, VulkanSwapchain>>,
destroyed_swapchains: Mutex<SwapchainDestroyQueue>,
- texture_pool: Mutex<Pool<VulkanTextureHolder>>,
+ image_pool: Mutex<Pool<VulkanImageHolder>>,
buffer_pool: Mutex<Pool<VulkanBuffer>>,
sampler_pool: Mutex<Pool<VulkanSampler>>,
bind_group_layout_pool: Mutex<Pool<VulkanBindGroupLayout>>,
swapchains: Mutex::new(HashMap::new()),
destroyed_swapchains: Mutex::new(DelayQueue::new(SWAPCHAIN_DESTROY_DELAY_FRAMES)),
- texture_pool: default(),
+ image_pool: default(),
buffer_pool: default(),
sampler_pool: default(),
bind_group_layout_pool: default(),
Buffer(handle)
}
- fn create_texture(&self, desc: &TextureDesc) -> Texture {
+ fn create_image(&self, desc: &ImageDesc) -> Image {
debug_assert_ne!(desc.layer_count, 0, "layers must be at least one");
debug_assert_ne!(desc.width, 0, "width must be at least one");
debug_assert_ne!(desc.height, 0, "height must be at least one");
debug_assert_ne!(desc.depth, 0, "depth must be at least one");
- if desc.dimension == TextureDimension::Type3d {
+ if desc.dimension == ImageDimension::Type3d {
debug_assert_eq!(desc.layer_count, 1, "3d image arrays are illegal");
}
- if desc.dimension == TextureDimension::TypeCube {
+ if desc.dimension == ImageDimension::TypeCube {
debug_assert!(
desc.layer_count % 6 == 0,
"cubemaps must have 6 layers each"
}
let mut flags = vk::ImageCreateFlags::default();
- if desc.dimension == TextureDimension::TypeCube {
+ if desc.dimension == ImageDimension::TypeCube {
flags |= vk::ImageCreateFlags::CUBE_COMPATIBLE
}
let image_type = match desc.dimension {
- TextureDimension::Type1d => vk::ImageType::Type1d,
- TextureDimension::Type2d => vk::ImageType::Type2d,
- TextureDimension::Type3d => vk::ImageType::Type3d,
- TextureDimension::TypeCube => vk::ImageType::Type2d,
+ ImageDimension::Type1d => vk::ImageType::Type1d,
+ ImageDimension::Type2d => vk::ImageType::Type2d,
+ ImageDimension::Type3d => vk::ImageType::Type3d,
+ ImageDimension::TypeCube => vk::ImageType::Type2d,
};
let format = vulkan_format(desc.format);
let extent = vk::Extent3d {
};
let mut usage = default();
- if desc.usage.contains(TextureUsageFlags::SAMPLED) {
+ if desc.usage.contains(ImageUsageFlags::SAMPLED) {
usage |= vk::ImageUsageFlags::SAMPLED;
}
- if desc.usage.contains(TextureUsageFlags::STORAGE) {
+ if desc.usage.contains(ImageUsageFlags::STORAGE) {
usage |= vk::ImageUsageFlags::STORAGE;
}
- if desc.usage.contains(TextureUsageFlags::DEPTH_STENCIL) {
+ if desc.usage.contains(ImageUsageFlags::DEPTH_STENCIL) {
usage |= vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT;
}
- if desc.usage.contains(TextureUsageFlags::RENDER_TARGET) {
+ if desc.usage.contains(ImageUsageFlags::RENDER_TARGET) {
usage |= vk::ImageUsageFlags::COLOR_ATTACHMENT;
}
- if desc.usage.contains(TextureUsageFlags::TRANSFER_DST) {
+ if desc.usage.contains(ImageUsageFlags::TRANSFER_DST) {
usage |= vk::ImageUsageFlags::TRANSFER_DST;
}
- if desc.usage.contains(TextureUsageFlags::TRANSFER_SRC) {
+ if desc.usage.contains(ImageUsageFlags::TRANSFER_SRC) {
usage |= vk::ImageUsageFlags::TRANSFER_SRC;
}
.device_fn
.create_image_view(self.device, &create_info, None, &mut view));
- let texture = VulkanTextureUnique {
- texture: VulkanTexture { image, memory },
+ let image = VulkanImageUnique {
+ image: VulkanImage { image, memory },
view,
};
let handle = self
- .texture_pool
+ .image_pool
.lock()
- .insert(VulkanTextureHolder::Unique(texture));
+ .insert(VulkanImageHolder::Unique(image));
- Texture(handle)
+ Image(handle)
}
- fn create_texture_view(&self, desc: &TextureViewDesc) -> Texture {
- let mut texture_pool = self.texture_pool.lock();
- let texture = texture_pool.get_mut(desc.texture.0).unwrap();
+ fn create_image_view(&self, desc: &ImageViewDesc) -> Image {
+ let mut image_pool = self.image_pool.lock();
+ let image = image_pool.get_mut(desc.image.0).unwrap();
- let arc_texture;
- match texture {
- VulkanTextureHolder::Shared(shared) => arc_texture = shared.texture.clone(),
- VulkanTextureHolder::Unique(unique) => {
- let unique_texture = ManualArc::new(unique.texture.clone());
- arc_texture = unique_texture.clone();
+ let arc_image;
+ match image {
+ VulkanImageHolder::Shared(shared) => arc_image = shared.image.clone(),
+ VulkanImageHolder::Unique(unique) => {
+ let unique_image = ManualArc::new(unique.image.clone());
+ arc_image = unique_image.clone();
let unique_view = unique.view;
- *texture = VulkanTextureHolder::Shared(VulkanTextureShared {
- texture: unique_texture,
+ *image = VulkanImageHolder::Shared(VulkanImageShared {
+ image: unique_image,
view: unique_view,
})
}
- VulkanTextureHolder::Swapchain(_) => {
+ VulkanImageHolder::Swapchain(_) => {
panic!("unable to create additional views of swapchain images")
}
}
let format = vulkan_format(desc.format);
let create_info = vk::ImageViewCreateInfo {
- image: arc_texture.image,
+ image: arc_image.image,
view_type,
format,
subresource_range,
.device_fn
.create_image_view(self.device, &create_info, None, &mut view));
- let handle = texture_pool.insert(VulkanTextureHolder::Shared(VulkanTextureShared {
- texture: arc_texture,
+ let handle = image_pool.insert(VulkanImageHolder::Shared(VulkanImageShared {
+ image: arc_image,
view,
}));
- Texture(handle)
+ Image(handle)
}
fn create_sampler(&self, desc: &SamplerDesc) -> Sampler {
}
}
- fn destroy_texture(&self, frame: &Frame, texture: Texture) {
- if let Some(texture) = self.texture_pool.lock().remove(texture.0) {
+ fn destroy_image(&self, frame: &Frame, image: Image) {
+ if let Some(image_holder) = self.image_pool.lock().remove(image.0) {
let frame = self.frame(frame);
- match texture {
- // The texture is unique, we've never allocated a reference counted object for it.
- VulkanTextureHolder::Unique(texture) => {
- frame.destroyed_image_views.lock().push_back(texture.view);
- frame
- .destroyed_images
- .lock()
- .push_back(texture.texture.image);
+ match image_holder {
+ // The image is unique, we've never allocated a reference counted object for it.
+ VulkanImageHolder::Unique(image) => {
+ frame.destroyed_image_views.lock().push_back(image.view);
+ frame.destroyed_images.lock().push_back(image.image.image);
frame
.destroyed_allocations
.lock()
- .push_back(texture.texture.memory);
+ .push_back(image.image.memory);
}
- // The texture was at one point shared, we may or may not have the last reference.
- VulkanTextureHolder::Shared(texture) => {
- frame.destroyed_image_views.lock().push_back(texture.view);
+ // The image was at one point shared, we may or may not have the last reference.
+ VulkanImageHolder::Shared(image) => {
+ frame.destroyed_image_views.lock().push_back(image.view);
// If we had the last reference we need to destroy the image and memory too
- if let manual_arc::Release::Unique(texture) = texture.texture.release() {
- frame.destroyed_images.lock().push_back(texture.image);
- frame.destroyed_allocations.lock().push_back(texture.memory);
+ if let manual_arc::Release::Unique(image) = image.image.release() {
+ frame.destroyed_images.lock().push_back(image.image);
+ frame.destroyed_allocations.lock().push_back(image.memory);
}
}
- VulkanTextureHolder::Swapchain(_) => {
+ VulkanImageHolder::Swapchain(_) => {
panic!("cannot directly destroy swapchain images")
}
}
capabilities: _,
}) = self.swapchains.lock().remove(&window)
{
- let mut texture_pool = self.texture_pool.lock();
+ let mut image_pool = self.image_pool.lock();
if let VulkanSwapchainState::Occupied {
width: _,
{
let mut vulkan_image_views = Vec::new();
for &image_view in image_views.iter() {
- match texture_pool.remove(image_view.0) {
- Some(VulkanTextureHolder::Swapchain(VulkanTextureSwapchain {
+ match image_pool.remove(image_view.0) {
+ Some(VulkanImageHolder::Swapchain(VulkanImageSwapchain {
window: _,
image: _,
view,
})) => vulkan_image_views.push(view),
- _ => panic!("swapchain texture in wrong state"),
+ _ => panic!("swapchain image in wrong state"),
}
}
&self,
frame: &Frame,
window: Window,
- format: TextureFormat,
- ) -> (u32, u32, Texture) {
+ format: ImageFormat,
+ ) -> (u32, u32, Image) {
let format = vulkan_format(format);
let mut swapchains = self.swapchains.lock();
assert_eq!(format, vulkan_swapchain.surface_format.format);
let frame = self.frame(frame);
- let mut texture_pool = self.texture_pool.lock();
+ let mut image_pool = self.image_pool.lock();
let mut present_swapchains = frame.present_swapchains.lock();
let present_info = match present_swapchains.entry(window) {
&mut view,
));
- let handle = texture_pool.insert(VulkanTextureHolder::Swapchain(
- VulkanTextureSwapchain {
+ let handle = image_pool.insert(VulkanImageHolder::Swapchain(
+ VulkanImageSwapchain {
window,
image,
view,
},
));
- Texture(handle)
+ Image(handle)
})
.collect::<Box<_>>();
image_views,
} => {
let destroy_image_views =
- |textures: &mut Pool<VulkanTextureHolder>| -> Box<[vk::ImageView]> {
+ |images: &mut Pool<VulkanImageHolder>| -> Box<[vk::ImageView]> {
let mut vulkan_image_views = Vec::new();
for &image_view in image_views.iter() {
- match textures.remove(image_view.0) {
- Some(VulkanTextureHolder::Swapchain(
- VulkanTextureSwapchain {
- window: _,
- image: _,
- view,
- },
- )) => vulkan_image_views.push(view),
- _ => panic!("swapchain texture in wrong state"),
+ match images.remove(image_view.0) {
+ Some(VulkanImageHolder::Swapchain(VulkanImageSwapchain {
+ window: _,
+ image: _,
+ view,
+ })) => vulkan_image_views.push(view),
+ _ => panic!("swapchain image in wrong state"),
}
}
vulkan_image_views.into_boxed_slice()
};
if *width != desired_width || *height != desired_height || *suboptimal {
- let image_views = destroy_image_views(&mut texture_pool);
+ let image_views = destroy_image_views(&mut image_pool);
old_swapchain = *swapchain;
if !old_swapchain.is_null() {
self.destroyed_swapchains.lock().push((
}
vk::Result::ErrorOutOfDateKHR => {
old_swapchain = *swapchain;
- let image_views = destroy_image_views(&mut texture_pool);
+ let image_views = destroy_image_views(&mut image_pool);
if !old_swapchain.is_null() {
self.destroyed_swapchains.lock().push((
Window::default(),
&self,
cmd_buffer: &mut CmdBuffer,
global_barrier: Option<&GlobalBarrier>,
- texture_barriers: &[TextureBarrier],
+ image_barriers: &[ImageBarrier],
) {
let arena = HybridArena::<4096>::new();
);
let image_memory_barriers =
- arena.alloc_slice_fill_iter(texture_barriers.iter().map(|texture_barrier| {
+ arena.alloc_slice_fill_iter(image_barriers.iter().map(|image_barrier| {
let image = self
- .texture_pool
+ .image_pool
.lock()
- .get(texture_barrier.texture.0)
- .expect("invalid texture handle")
+ .get(image_barrier.image.0)
+ .expect("invalid image handle")
.image();
// TODO: This needs to be pulled from somewhere useful.
base_array_layer: 0,
layer_count: 1,
};
- vulkan_image_memory_barrier(texture_barrier, image, subresource_range)
+ vulkan_image_memory_barrier(image_barrier, image, subresource_range)
}));
let command_buffer = self.cmd_buffer_mut(cmd_buffer).command_buffer;
}
}
- fn cmd_copy_buffer_to_texture(
+ fn cmd_copy_buffer_to_image(
&self,
cmd_buffer: &mut CmdBuffer,
src_buffer: Buffer,
- dst_texture: Texture,
- dst_texture_layout: TextureLayout,
- copies: &[BufferTextureCopy],
+ dst_image: Image,
+ dst_image_layout: ImageLayout,
+ copies: &[BufferImageCopy],
) {
let arena = HybridArena::<4096>::new();
buffer_offset: copy.buffer_offset,
buffer_row_length: copy.buffer_row_length,
buffer_image_height: copy.buffer_image_height,
- image_subresource: vulkan_subresource_layers(©.texture_subresource_layers),
- image_offset: copy.texture_offset.into(),
- image_extent: copy.texture_extent.into(),
+ image_subresource: vulkan_subresource_layers(©.image_subresource_layers),
+ image_offset: copy.image_offset.into(),
+ image_extent: copy.image_extent.into(),
}));
let src_buffer = self
.buffer;
let dst_image = self
- .texture_pool
+ .image_pool
.lock()
- .get(dst_texture.0)
- .expect("invalid texture handle")
+ .get(dst_image.0)
+ .expect("invalid image handle")
.image();
- let dst_image_layout = match dst_texture_layout {
- TextureLayout::Optimal => vk::ImageLayout::TransferDstOptimal,
- TextureLayout::General => vk::ImageLayout::General,
+ let dst_image_layout = match dst_image_layout {
+ ImageLayout::Optimal => vk::ImageLayout::TransferDstOptimal,
+ ImageLayout::General => vk::ImageLayout::General,
};
let command_buffer = self.cmd_buffer_mut(cmd_buffer).command_buffer;
..default()
}
}
- TypedBind::Texture(textures) => {
- let image_infos_iter = textures.iter().map(|texture| {
- let image_view = self
- .texture_pool
- .lock()
- .get(texture.0)
- .unwrap()
- .image_view();
+ TypedBind::Image(images) => {
+ let image_infos_iter = images.iter().map(|image| {
+ let image_view = self.image_pool.lock().get(image.0).unwrap().image_view();
vk::DescriptorImageInfo {
image_layout: vk::ImageLayout::ShaderReadOnlyOptimal, // TODO: Determine appropriate layout here.
image_view,
.color_attachments
.iter()
.map(|attachment| {
- let image_view = match self.texture_pool.lock().get(attachment.texture.0).unwrap() {
- VulkanTextureHolder::Unique(texture) => texture.view,
- VulkanTextureHolder::Shared(texture) => texture.view,
- VulkanTextureHolder::Swapchain(texture) => {
+ let image_view = match self.image_pool.lock().get(attachment.image.0).unwrap() {
+ VulkanImageHolder::Unique(image) => image.view,
+ VulkanImageHolder::Shared(image) => image.view,
+ VulkanImageHolder::Swapchain(image) => {
assert!(
- !cmd_buffer.swapchains_touched.contains_key(&texture.window),
+ !cmd_buffer.swapchains_touched.contains_key(&image.window),
"swapchain attached multiple times in a command buffer"
);
cmd_buffer.swapchains_touched.insert(
- texture.window,
+ image.window,
(
- texture.image,
+ image.image,
vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
),
);
dst_queue_family_index: self.universal_queue_family_index,
old_layout: vk::ImageLayout::Undefined,
new_layout: vk::ImageLayout::AttachmentOptimal,
- image: texture.image,
+ image: image.image,
subresource_range: vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
.cmd_pipeline_barrier2(cmd_buffer.command_buffer, &dependency_info)
};
- texture.view
+ image.view
}
};
.collect::<Vec<_>>();
let depth_attachment = desc.depth_attachment.as_ref().map(|attachment| {
- let image_view = match self.texture_pool.lock().get(attachment.texture.0).unwrap() {
- VulkanTextureHolder::Unique(texture) => texture.view,
- VulkanTextureHolder::Shared(texture) => texture.view,
- VulkanTextureHolder::Swapchain(_) => panic!(),
+ let image_view = match self.image_pool.lock().get(attachment.image.0).unwrap() {
+ VulkanImageHolder::Unique(image) => image.view,
+ VulkanImageHolder::Shared(image) => image.view,
+ VulkanImageHolder::Swapchain(_) => panic!(),
};
let (load_op, clear_value) = vulkan_load_op(attachment.load_op);
let mut image_views = Vec::new();
let mut images = Vec::new();
let mut memories = Vec::new();
- for texture in self.texture_pool.get_mut().values() {
- match texture {
- VulkanTextureHolder::Unique(texture) => {
- image_views.push(texture.view);
- images.push(texture.texture.image);
- memories.push(texture.texture.memory.memory);
+ for image in self.image_pool.get_mut().values() {
+ match image {
+ VulkanImageHolder::Unique(image) => {
+ image_views.push(image.view);
+ images.push(image.image.image);
+ memories.push(image.image.memory.memory);
}
- VulkanTextureHolder::Shared(texture) => {
- image_views.push(texture.view);
+ VulkanImageHolder::Shared(image) => {
+ image_views.push(image.view);
}
- VulkanTextureHolder::Swapchain(texture) => {
- image_views.push(texture.view);
+ VulkanImageHolder::Swapchain(image) => {
+ image_views.push(image.view);
}
}
}
use std::{path::Path, time::Instant};
use narcissus_app::{create_app, Event, Key, WindowDesc};
-use narcissus_core::{cstr, default, obj, rand::Pcg64, Image};
+use narcissus_core::{cstr, default, obj, rand::Pcg64, Texture};
use narcissus_gpu::{
create_vulkan_device, Access, Bind, BindGroupLayoutDesc, BindGroupLayoutEntryDesc, BindingType,
- Buffer, BufferDesc, BufferTextureCopy, BufferUsageFlags, ClearValue, CompareOp, CullingMode,
- Device, Extent2d, Extent3d, FrontFace, GraphicsPipelineDesc, GraphicsPipelineLayout, IndexType,
- LoadOp, MemoryLocation, Offset2d, Offset3d, PolygonMode, RenderingAttachment, RenderingDesc,
+ Buffer, BufferDesc, BufferImageCopy, BufferUsageFlags, ClearValue, CompareOp, CullingMode,
+ Device, Extent2d, Extent3d, FrontFace, GraphicsPipelineDesc, GraphicsPipelineLayout, Image,
+ ImageAspectFlags, ImageBarrier, ImageDesc, ImageDimension, ImageFormat, ImageLayout,
+ ImageSubresourceLayers, ImageSubresourceRange, ImageUsageFlags, IndexType, LoadOp,
+ MemoryLocation, Offset2d, Offset3d, PolygonMode, RenderingAttachment, RenderingDesc,
SamplerAddressMode, SamplerDesc, SamplerFilter, Scissor, ShaderDesc, ShaderStageFlags, StoreOp,
- Texture, TextureAspectFlags, TextureBarrier, TextureDesc, TextureDimension, TextureFormat,
- TextureLayout, TextureSubresourceLayers, TextureSubresourceRange, TextureUsageFlags,
ThreadToken, Topology, TypedBind, Viewport,
};
use narcissus_maths::{
(vertices, indices)
}
-fn load_img<P: AsRef<Path>>(path: P) -> Image {
+fn load_texture<P: AsRef<Path>>(path: P) -> Texture {
let start = std::time::Instant::now();
let path = path.as_ref();
- let image = Image::from_buffer(std::fs::read(path).expect("failed to read file").as_slice())
- .expect("failed to load image");
+ let texture =
+ Texture::from_buffer(std::fs::read(path).expect("failed to read file").as_slice())
+ .expect("failed to load image");
println!(
"loading image {path:?} took {:?}",
std::time::Instant::now() - start
);
- image
+ texture
}
fn create_buffer_with_data<T>(device: &dyn Device, usage: BufferUsageFlags, data: &[T]) -> Buffer
buffer
}
-fn create_texture_with_data(
+fn create_image_with_data(
device: &dyn Device,
thread_token: &mut ThreadToken,
width: u32,
height: u32,
data: &[u8],
-) -> Texture {
+) -> Image {
let frame = device.begin_frame();
let buffer = create_buffer_with_data(device, BufferUsageFlags::TRANSFER_SRC, data);
- let texture = device.create_texture(&TextureDesc {
+ let image = device.create_image(&ImageDesc {
memory_location: MemoryLocation::PreferDevice,
- usage: TextureUsageFlags::SAMPLED | TextureUsageFlags::TRANSFER_DST,
- dimension: TextureDimension::Type2d,
- format: TextureFormat::RGBA8_SRGB,
- initial_layout: TextureLayout::Optimal,
+ usage: ImageUsageFlags::SAMPLED | ImageUsageFlags::TRANSFER_DST,
+ dimension: ImageDimension::Type2d,
+ format: ImageFormat::RGBA8_SRGB,
+ initial_layout: ImageLayout::Optimal,
width,
height,
depth: 1,
device.cmd_barrier(
&mut cmd_buffer,
None,
- &[TextureBarrier {
+ &[ImageBarrier {
prev_access: &[Access::None],
next_access: &[Access::TransferWrite],
- prev_layout: TextureLayout::Optimal,
- next_layout: TextureLayout::Optimal,
- texture,
- subresource_range: TextureSubresourceRange {
- aspect: TextureAspectFlags::COLOR,
+ prev_layout: ImageLayout::Optimal,
+ next_layout: ImageLayout::Optimal,
+ image,
+ subresource_range: ImageSubresourceRange {
+ aspect: ImageAspectFlags::COLOR,
base_mip_level: 0,
mip_level_count: 1,
base_array_layer: 0,
}],
);
- device.cmd_copy_buffer_to_texture(
+ device.cmd_copy_buffer_to_image(
&mut cmd_buffer,
buffer,
- texture,
- TextureLayout::Optimal,
- &[BufferTextureCopy {
+ image,
+ ImageLayout::Optimal,
+ &[BufferImageCopy {
buffer_offset: 0,
buffer_row_length: 0,
buffer_image_height: 0,
- texture_subresource_layers: TextureSubresourceLayers {
- aspect: TextureAspectFlags::COLOR,
+ image_subresource_layers: ImageSubresourceLayers {
+ aspect: ImageAspectFlags::COLOR,
mip_level: 0,
base_array_layer: 0,
array_layer_count: 1,
},
- texture_offset: Offset3d { x: 0, y: 0, z: 0 },
- texture_extent: Extent3d {
+ image_offset: Offset3d { x: 0, y: 0, z: 0 },
+ image_extent: Extent3d {
width,
height,
depth: 1,
device.cmd_barrier(
&mut cmd_buffer,
None,
- &[TextureBarrier {
+ &[ImageBarrier {
prev_access: &[Access::TransferWrite],
next_access: &[Access::FragmentShaderSampledImageRead],
- prev_layout: TextureLayout::Optimal,
- next_layout: TextureLayout::Optimal,
- texture,
- subresource_range: TextureSubresourceRange {
- aspect: TextureAspectFlags::COLOR,
+ prev_layout: ImageLayout::Optimal,
+ next_layout: ImageLayout::Optimal,
+ image,
+ subresource_range: ImageSubresourceRange {
+ aspect: ImageAspectFlags::COLOR,
base_mip_level: 0,
mip_level_count: 1,
base_array_layer: 0,
device.end_frame(frame);
- texture
+ image
}
struct MappedBuffer<'a> {
}
pub fn main() {
- let blåhaj_image = load_img("narcissus/data/blåhaj.png");
+ let blåhaj_image = load_texture("narcissus/data/blåhaj.png");
let (blåhaj_vertices, blåhaj_indices) = load_obj("narcissus/data/blåhaj.obj");
let app = create_app();
BindGroupLayoutEntryDesc {
slot: 3,
stages: ShaderStageFlags::ALL,
- binding_type: BindingType::Texture,
+ binding_type: BindingType::Image,
count: 1,
},
],
},
bind_group_layouts: &[uniform_bind_group_layout, storage_bind_group_layout],
layout: GraphicsPipelineLayout {
- color_attachment_formats: &[TextureFormat::BGRA8_SRGB],
- depth_attachment_format: Some(TextureFormat::DEPTH_F32),
+ color_attachment_formats: &[ImageFormat::BGRA8_SRGB],
+ depth_attachment_format: Some(ImageFormat::DEPTH_F32),
stencil_attachment_format: None,
},
topology: Topology::Triangles,
blåhaj_indices.as_slice(),
);
- let blåhaj_texture = create_texture_with_data(
+ let blåhaj_image = create_image_with_data(
device.as_ref(),
&mut thread_token,
blåhaj_image.width() as u32,
}
let (width, height, swapchain_image) =
- device.acquire_swapchain(&frame, main_window, TextureFormat::BGRA8_SRGB);
+ device.acquire_swapchain(&frame, main_window, ImageFormat::BGRA8_SRGB);
let frame_start = Instant::now() - start_time;
let frame_start = frame_start.as_secs_f32() * 0.01;
uniforms.write(Uniforms { clip_from_model });
if width != depth_width || height != depth_height {
- device.destroy_texture(&frame, depth_image);
- depth_image = device.create_texture(&TextureDesc {
+ device.destroy_image(&frame, depth_image);
+ depth_image = device.create_image(&ImageDesc {
memory_location: MemoryLocation::PreferDevice,
- usage: TextureUsageFlags::DEPTH_STENCIL,
- dimension: TextureDimension::Type2d,
- format: TextureFormat::DEPTH_F32,
- initial_layout: TextureLayout::Optimal,
+ usage: ImageUsageFlags::DEPTH_STENCIL,
+ dimension: ImageDimension::Type2d,
+ format: ImageFormat::DEPTH_F32,
+ initial_layout: ImageLayout::Optimal,
width,
height,
depth: 1,
Bind {
binding: 3,
array_element: 0,
- typed: TypedBind::Texture(&[blåhaj_texture]),
+ typed: TypedBind::Image(&[blåhaj_image]),
},
],
);
width,
height,
color_attachments: &[RenderingAttachment {
- texture: swapchain_image,
+ image: swapchain_image,
load_op: LoadOp::Clear(ClearValue::ColorF32([
0.392157, 0.584314, 0.929412, 1.0,
])),
store_op: StoreOp::Store,
}],
depth_attachment: Some(RenderingAttachment {
- texture: depth_image,
+ image: depth_image,
load_op: LoadOp::Clear(ClearValue::DepthStencil {
depth: 0.0,
stencil: 0,