Skip to main content

lgpu/
texture.rs

1//! GPU texture, image views, and samplers.
2
3use crate::TextureFormat;
4use std::sync::Arc;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub struct TextureId(pub u32);
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub struct SamplerId(pub u32);
11
12pub struct Texture {
13    pub(crate) hal_texture: Option<lgpu_hal::vulkan::VulkanTexture>,
14    pub(crate) vulkan_device: Arc<lgpu_hal::vulkan::VulkanDevice>,
15    pub width: u32,
16    pub height: u32,
17    pub format: TextureFormat,
18    pub id: Option<TextureId>,
19    pub storage_id: Option<TextureId>,
20    pub owned: bool,
21}
22
23impl std::fmt::Debug for Texture {
24    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25        f.debug_struct("Texture")
26            .field("width", &self.width)
27            .field("height", &self.height)
28            .field("format", &self.format)
29            .field("id", &self.id)
30            .field("storage_id", &self.storage_id)
31            .field("owned", &self.owned)
32            .finish()
33    }
34}
35
36pub struct Sampler {
37    pub(crate) hal_sampler: Option<lgpu_hal::vulkan::VulkanSampler>,
38    pub(crate) vulkan_device: Arc<lgpu_hal::vulkan::VulkanDevice>,
39    pub id: Option<SamplerId>,
40}
41
42impl std::fmt::Debug for Sampler {
43    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44        f.debug_struct("Sampler").field("id", &self.id).finish()
45    }
46}
47
48impl Texture {
49    pub fn id(&self) -> Option<TextureId> {
50        self.id
51    }
52
53    pub fn storage_id(&self) -> Option<TextureId> {
54        self.storage_id
55    }
56
57    pub fn is_owned(&self) -> bool {
58        self.owned
59    }
60
61    pub fn clone_unowned(&self) -> Self {
62        Self {
63            hal_texture: self
64                .hal_texture
65                .as_ref()
66                .map(|t| lgpu_hal::vulkan::VulkanTexture {
67                    image: t.image,
68                    view: t.view,
69                    memory: t.memory,
70                    block_id: t.block_id,
71                    offset: t.offset,
72                    allocated_size: t.allocated_size,
73                    layout: std::sync::Mutex::new(t.current_layout()),
74                    width: t.width,
75                    height: t.height,
76                    mip_levels: t.mip_levels,
77                    sample_count: t.sample_count,
78                    format: t.format,
79                    owned: false,
80                }),
81            vulkan_device: Arc::clone(&self.vulkan_device),
82            width: self.width,
83            height: self.height,
84            format: self.format,
85            id: self.id,
86            storage_id: self.storage_id,
87            owned: false,
88        }
89    }
90}
91
92impl Sampler {
93    pub fn id(&self) -> Option<SamplerId> {
94        self.id
95    }
96}
97
98impl Drop for Texture {
99    fn drop(&mut self) {
100        if self.owned {
101            if let Some(tex_id) = self.id {
102                self.vulkan_device.unregister_bindless_texture(tex_id.0);
103            }
104            if let Some(storage_id) = self.storage_id {
105                self.vulkan_device
106                    .unregister_bindless_storage_image(storage_id.0);
107            }
108            if let Some(tex) = self.hal_texture.take() {
109                self.vulkan_device.destroy_texture(tex);
110            }
111        }
112    }
113}
114
115impl Drop for Sampler {
116    fn drop(&mut self) {
117        if let Some(sampler_id) = self.id {
118            self.vulkan_device.unregister_bindless_sampler(sampler_id.0);
119        }
120        if let Some(sampler) = self.hal_sampler.take() {
121            self.vulkan_device.destroy_sampler(sampler);
122        }
123    }
124}