mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
[vk] remove usage of imageless framebuffers
Imageless framebuffers are not needed, we know which views will be attached to the render pass already. Even if we wanted to more aggressively cache imageless framebuffers that wouldn't be possible since they still require specifiying view usage, texture usage and view formats. Removing usage of imageless framebuffers simplifies the code substantially.
This commit is contained in:
parent
2bb8325f85
commit
d4b46d6099
@ -44,9 +44,6 @@ pub struct PhysicalDeviceFeatures {
|
||||
pub(super) descriptor_indexing:
|
||||
Option<vk::PhysicalDeviceDescriptorIndexingFeaturesEXT<'static>>,
|
||||
|
||||
/// Features provided by `VK_KHR_imageless_framebuffer`, promoted to Vulkan 1.2.
|
||||
imageless_framebuffer: Option<vk::PhysicalDeviceImagelessFramebufferFeaturesKHR<'static>>,
|
||||
|
||||
/// Features provided by `VK_KHR_timeline_semaphore`, promoted to Vulkan 1.2
|
||||
timeline_semaphore: Option<vk::PhysicalDeviceTimelineSemaphoreFeaturesKHR<'static>>,
|
||||
|
||||
@ -138,9 +135,6 @@ impl PhysicalDeviceFeatures {
|
||||
if let Some(ref mut feature) = self.descriptor_indexing {
|
||||
info = info.push_next(feature);
|
||||
}
|
||||
if let Some(ref mut feature) = self.imageless_framebuffer {
|
||||
info = info.push_next(feature);
|
||||
}
|
||||
if let Some(ref mut feature) = self.timeline_semaphore {
|
||||
info = info.push_next(feature);
|
||||
}
|
||||
@ -329,16 +323,6 @@ impl PhysicalDeviceFeatures {
|
||||
} else {
|
||||
None
|
||||
},
|
||||
imageless_framebuffer: if device_api_version >= vk::API_VERSION_1_2
|
||||
|| enabled_extensions.contains(&khr::imageless_framebuffer::NAME)
|
||||
{
|
||||
Some(
|
||||
vk::PhysicalDeviceImagelessFramebufferFeaturesKHR::default()
|
||||
.imageless_framebuffer(private_caps.imageless_framebuffers),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
timeline_semaphore: if device_api_version >= vk::API_VERSION_1_2
|
||||
|| enabled_extensions.contains(&khr::timeline_semaphore::NAME)
|
||||
{
|
||||
@ -976,15 +960,6 @@ impl PhysicalDeviceProperties {
|
||||
extensions.push(khr::image_format_list::NAME);
|
||||
}
|
||||
|
||||
// Optional `VK_KHR_imageless_framebuffer`
|
||||
if self.supports_extension(khr::imageless_framebuffer::NAME) {
|
||||
extensions.push(khr::imageless_framebuffer::NAME);
|
||||
// Require `VK_KHR_maintenance2` due to it being a dependency
|
||||
if self.device_api_version < vk::API_VERSION_1_1 {
|
||||
extensions.push(khr::maintenance2::NAME);
|
||||
}
|
||||
}
|
||||
|
||||
// Optional `VK_KHR_driver_properties`
|
||||
if self.supports_extension(khr::driver_properties::NAME) {
|
||||
extensions.push(khr::driver_properties::NAME);
|
||||
@ -1420,15 +1395,6 @@ impl super::InstanceShared {
|
||||
features2 = features2.push_next(next);
|
||||
}
|
||||
|
||||
// `VK_KHR_imageless_framebuffer` is promoted to 1.2, but has no
|
||||
// changes, so we can keep using the extension unconditionally.
|
||||
if capabilities.supports_extension(khr::imageless_framebuffer::NAME) {
|
||||
let next = features
|
||||
.imageless_framebuffer
|
||||
.insert(vk::PhysicalDeviceImagelessFramebufferFeaturesKHR::default());
|
||||
features2 = features2.push_next(next);
|
||||
}
|
||||
|
||||
// `VK_KHR_timeline_semaphore` is promoted to 1.2, but has no
|
||||
// changes, so we can keep using the extension unconditionally.
|
||||
if capabilities.supports_extension(khr::timeline_semaphore::NAME) {
|
||||
@ -1655,12 +1621,6 @@ impl super::Instance {
|
||||
}
|
||||
|
||||
let private_caps = super::PrivateCapabilities {
|
||||
imageless_framebuffers: match phd_features.imageless_framebuffer {
|
||||
Some(features) => features.imageless_framebuffer == vk::TRUE,
|
||||
None => phd_features
|
||||
.imageless_framebuffer
|
||||
.is_some_and(|ext| ext.imageless_framebuffer != 0),
|
||||
},
|
||||
image_view_usage: phd_capabilities.device_api_version >= vk::API_VERSION_1_1
|
||||
|| phd_capabilities.supports_extension(khr::maintenance2::NAME),
|
||||
timeline_semaphores: match phd_features.timeline_semaphore {
|
||||
|
||||
@ -714,7 +714,6 @@ impl crate::CommandEncoder for super::CommandEncoder {
|
||||
) -> Result<(), crate::DeviceError> {
|
||||
let mut vk_clear_values =
|
||||
ArrayVec::<vk::ClearValue, { super::MAX_TOTAL_ATTACHMENTS }>::new();
|
||||
let mut vk_image_views = ArrayVec::<vk::ImageView, { super::MAX_TOTAL_ATTACHMENTS }>::new();
|
||||
let mut rp_key = super::RenderPassKey::default();
|
||||
let mut fb_key = super::FramebufferKey {
|
||||
attachments: ArrayVec::default(),
|
||||
@ -728,7 +727,6 @@ impl crate::CommandEncoder for super::CommandEncoder {
|
||||
vk_clear_values.push(vk::ClearValue {
|
||||
color: unsafe { cat.make_vk_clear_color() },
|
||||
});
|
||||
vk_image_views.push(cat.target.view.raw);
|
||||
let color = super::ColorAttachmentKey {
|
||||
base: cat.target.make_attachment_key(cat.ops, caps),
|
||||
resolve: cat.resolve_target.as_ref().map(|target| {
|
||||
@ -737,11 +735,10 @@ impl crate::CommandEncoder for super::CommandEncoder {
|
||||
};
|
||||
|
||||
rp_key.colors.push(Some(color));
|
||||
fb_key.attachments.push(cat.target.view.attachment.clone());
|
||||
fb_key.attachments.push(cat.target.view.raw);
|
||||
if let Some(ref at) = cat.resolve_target {
|
||||
vk_clear_values.push(unsafe { mem::zeroed() });
|
||||
vk_image_views.push(at.view.raw);
|
||||
fb_key.attachments.push(at.view.attachment.clone());
|
||||
fb_key.attachments.push(at.view.raw);
|
||||
}
|
||||
|
||||
// Assert this attachment is valid for the detected multiview, as a sanity check
|
||||
@ -763,12 +760,11 @@ impl crate::CommandEncoder for super::CommandEncoder {
|
||||
stencil: ds.clear_value.1,
|
||||
},
|
||||
});
|
||||
vk_image_views.push(ds.target.view.raw);
|
||||
rp_key.depth_stencil = Some(super::DepthStencilAttachmentKey {
|
||||
base: ds.target.make_attachment_key(ds.depth_ops, caps),
|
||||
stencil_ops: ds.stencil_ops,
|
||||
});
|
||||
fb_key.attachments.push(ds.target.view.attachment.clone());
|
||||
fb_key.attachments.push(ds.target.view.raw);
|
||||
|
||||
// Assert this attachment is valid for the detected multiview, as a sanity check
|
||||
// The driver crash for this is really bad on AMD, so the check is worth it
|
||||
@ -801,19 +797,11 @@ impl crate::CommandEncoder for super::CommandEncoder {
|
||||
.make_framebuffer(fb_key, raw_pass, desc.label)
|
||||
.unwrap();
|
||||
|
||||
let mut vk_info = vk::RenderPassBeginInfo::default()
|
||||
let vk_info = vk::RenderPassBeginInfo::default()
|
||||
.render_pass(raw_pass)
|
||||
.render_area(render_area)
|
||||
.clear_values(&vk_clear_values)
|
||||
.framebuffer(raw_framebuffer);
|
||||
let mut vk_attachment_info = if caps.imageless_framebuffers {
|
||||
Some(vk::RenderPassAttachmentBeginInfo::default().attachments(&vk_image_views))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(attachment_info) = vk_attachment_info.as_mut() {
|
||||
vk_info = vk_info.push_next(attachment_info);
|
||||
}
|
||||
|
||||
if let Some(label) = desc.label {
|
||||
unsafe { self.begin_debug_marker(label) };
|
||||
|
||||
@ -188,8 +188,8 @@ impl crate::Attachment<'_, super::TextureView> {
|
||||
caps: &super::PrivateCapabilities,
|
||||
) -> super::AttachmentKey {
|
||||
super::AttachmentKey {
|
||||
format: caps.map_texture_format(self.view.attachment.view_format),
|
||||
layout: derive_image_layout(self.usage, self.view.attachment.view_format),
|
||||
format: caps.map_texture_format(self.view.view_format),
|
||||
layout: derive_image_layout(self.usage, self.view.view_format),
|
||||
ops,
|
||||
}
|
||||
}
|
||||
@ -201,7 +201,6 @@ impl crate::ColorAttachment<'_, super::TextureView> {
|
||||
match self
|
||||
.target
|
||||
.view
|
||||
.attachment
|
||||
.view_format
|
||||
.sample_type(None, None)
|
||||
.unwrap()
|
||||
|
||||
@ -211,72 +211,18 @@ impl super::DeviceShared {
|
||||
Ok(match self.framebuffers.lock().entry(key) {
|
||||
Entry::Occupied(e) => *e.get(),
|
||||
Entry::Vacant(e) => {
|
||||
let vk_views = e
|
||||
.key()
|
||||
.attachments
|
||||
.iter()
|
||||
.map(|at| at.raw)
|
||||
.collect::<ArrayVec<_, { super::MAX_TOTAL_ATTACHMENTS }>>();
|
||||
let vk_view_formats = e
|
||||
.key()
|
||||
.attachments
|
||||
.iter()
|
||||
.map(|at| self.private_caps.map_texture_format(at.view_format))
|
||||
.collect::<ArrayVec<_, { super::MAX_TOTAL_ATTACHMENTS }>>();
|
||||
let vk_view_formats_list = e
|
||||
.key()
|
||||
.attachments
|
||||
.iter()
|
||||
.map(|at| at.raw_view_formats.clone())
|
||||
.collect::<ArrayVec<_, { super::MAX_TOTAL_ATTACHMENTS }>>();
|
||||
|
||||
let vk_image_infos = e
|
||||
.key()
|
||||
.attachments
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, at)| {
|
||||
let mut info = vk::FramebufferAttachmentImageInfo::default()
|
||||
.usage(conv::map_texture_usage(at.view_usage))
|
||||
.flags(at.raw_image_flags)
|
||||
.width(e.key().extent.width)
|
||||
.height(e.key().extent.height)
|
||||
.layer_count(e.key().extent.depth_or_array_layers);
|
||||
// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkRenderPassBeginInfo.html#VUID-VkRenderPassBeginInfo-framebuffer-03214
|
||||
if vk_view_formats_list[i].is_empty() {
|
||||
info = info.view_formats(&vk_view_formats[i..i + 1]);
|
||||
} else {
|
||||
info = info.view_formats(&vk_view_formats_list[i]);
|
||||
};
|
||||
info
|
||||
})
|
||||
.collect::<ArrayVec<_, { super::MAX_TOTAL_ATTACHMENTS }>>();
|
||||
|
||||
let mut vk_attachment_info = vk::FramebufferAttachmentsCreateInfo::default()
|
||||
.attachment_image_infos(&vk_image_infos);
|
||||
let mut vk_info = vk::FramebufferCreateInfo::default()
|
||||
let vk_info = vk::FramebufferCreateInfo::default()
|
||||
.render_pass(raw_pass)
|
||||
.width(e.key().extent.width)
|
||||
.height(e.key().extent.height)
|
||||
.layers(e.key().extent.depth_or_array_layers);
|
||||
.layers(e.key().extent.depth_or_array_layers)
|
||||
.attachments(&e.key().attachments);
|
||||
|
||||
if self.private_caps.imageless_framebuffers {
|
||||
//TODO: https://github.com/MaikKlein/ash/issues/450
|
||||
vk_info = vk_info
|
||||
.flags(vk::FramebufferCreateFlags::IMAGELESS_KHR)
|
||||
.push_next(&mut vk_attachment_info);
|
||||
vk_info.attachment_count = e.key().attachments.len() as u32;
|
||||
} else {
|
||||
vk_info = vk_info.attachments(&vk_views);
|
||||
}
|
||||
|
||||
*e.insert(unsafe {
|
||||
let raw = self.raw.create_framebuffer(&vk_info, None).unwrap();
|
||||
let raw = unsafe { self.raw.create_framebuffer(&vk_info, None).unwrap() };
|
||||
if let Some(label) = pass_label {
|
||||
self.set_object_name(raw, label);
|
||||
unsafe { self.set_object_name(raw, label) };
|
||||
}
|
||||
raw
|
||||
})
|
||||
*e.insert(raw)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -558,7 +504,6 @@ impl super::Device {
|
||||
let original_format = self.shared.private_caps.map_texture_format(config.format);
|
||||
let mut raw_flags = vk::SwapchainCreateFlagsKHR::empty();
|
||||
let mut raw_view_formats: Vec<vk::Format> = vec![];
|
||||
let mut wgt_view_formats = vec![];
|
||||
if !config.view_formats.is_empty() {
|
||||
raw_flags |= vk::SwapchainCreateFlagsKHR::MUTABLE_FORMAT;
|
||||
raw_view_formats = config
|
||||
@ -567,9 +512,6 @@ impl super::Device {
|
||||
.map(|f| self.shared.private_caps.map_texture_format(*f))
|
||||
.collect();
|
||||
raw_view_formats.push(original_format);
|
||||
|
||||
wgt_view_formats.clone_from(&config.view_formats);
|
||||
wgt_view_formats.push(config.format);
|
||||
}
|
||||
|
||||
let mut info = vk::SwapchainCreateInfoKHR::default()
|
||||
@ -639,12 +581,10 @@ impl super::Device {
|
||||
|
||||
Ok(super::Swapchain {
|
||||
raw,
|
||||
raw_flags,
|
||||
functor,
|
||||
device: Arc::clone(&self.shared),
|
||||
images,
|
||||
config: config.clone(),
|
||||
view_formats: wgt_view_formats,
|
||||
surface_semaphores,
|
||||
next_semaphore_index: 0,
|
||||
next_present_time: None,
|
||||
@ -686,11 +626,8 @@ impl super::Device {
|
||||
drop_guard,
|
||||
external_memory: None,
|
||||
block: None,
|
||||
usage: desc.usage,
|
||||
format: desc.format,
|
||||
raw_flags: vk::ImageCreateFlags::empty(),
|
||||
copy_size: desc.copy_extent(),
|
||||
view_formats,
|
||||
}
|
||||
}
|
||||
|
||||
@ -734,11 +671,8 @@ impl super::Device {
|
||||
|
||||
let original_format = self.shared.private_caps.map_texture_format(desc.format);
|
||||
let mut vk_view_formats = vec![];
|
||||
let mut wgt_view_formats = vec![];
|
||||
if !desc.view_formats.is_empty() {
|
||||
raw_flags |= vk::ImageCreateFlags::MUTABLE_FORMAT;
|
||||
wgt_view_formats.clone_from(&desc.view_formats);
|
||||
wgt_view_formats.push(desc.format);
|
||||
|
||||
if self.shared.private_caps.image_format_list {
|
||||
vk_view_formats = desc
|
||||
@ -788,8 +722,6 @@ impl super::Device {
|
||||
raw,
|
||||
requirements: req,
|
||||
copy_size,
|
||||
view_formats: wgt_view_formats,
|
||||
raw_flags,
|
||||
})
|
||||
}
|
||||
|
||||
@ -851,11 +783,8 @@ impl super::Device {
|
||||
drop_guard: None,
|
||||
external_memory: Some(memory),
|
||||
block: None,
|
||||
usage: desc.usage,
|
||||
format: desc.format,
|
||||
raw_flags: image.raw_flags,
|
||||
copy_size: image.copy_size,
|
||||
view_formats: image.view_formats,
|
||||
})
|
||||
}
|
||||
|
||||
@ -1326,11 +1255,8 @@ impl crate::Device for super::Device {
|
||||
drop_guard: None,
|
||||
external_memory: None,
|
||||
block: Some(block),
|
||||
usage: desc.usage,
|
||||
format: desc.format,
|
||||
raw_flags: image.raw_flags,
|
||||
copy_size: image.copy_size,
|
||||
view_formats: image.view_formats,
|
||||
})
|
||||
}
|
||||
unsafe fn destroy_texture(&self, texture: super::Texture) {
|
||||
@ -1369,14 +1295,11 @@ impl crate::Device for super::Device {
|
||||
NonZeroU32::new(subresource_range.layer_count).expect("Unexpected zero layer count");
|
||||
|
||||
let mut image_view_info;
|
||||
let view_usage = if self.shared.private_caps.image_view_usage && !desc.usage.is_empty() {
|
||||
if self.shared.private_caps.image_view_usage && !desc.usage.is_empty() {
|
||||
image_view_info =
|
||||
vk::ImageViewUsageCreateInfo::default().usage(conv::map_texture_usage(desc.usage));
|
||||
vk_info = vk_info.push_next(&mut image_view_info);
|
||||
desc.usage
|
||||
} else {
|
||||
texture.usage
|
||||
};
|
||||
}
|
||||
|
||||
let raw = unsafe { self.shared.raw.create_image_view(&vk_info, None) }
|
||||
.map_err(super::map_host_device_oom_and_ioca_err)?;
|
||||
@ -1385,39 +1308,23 @@ impl crate::Device for super::Device {
|
||||
unsafe { self.shared.set_object_name(raw, label) };
|
||||
}
|
||||
|
||||
let attachment = super::FramebufferAttachment {
|
||||
raw: if self.shared.private_caps.imageless_framebuffers {
|
||||
vk::ImageView::null()
|
||||
} else {
|
||||
raw
|
||||
},
|
||||
raw_image_flags: texture.raw_flags,
|
||||
view_usage,
|
||||
view_format: desc.format,
|
||||
raw_view_formats: texture
|
||||
.view_formats
|
||||
.iter()
|
||||
.map(|tf| self.shared.private_caps.map_texture_format(*tf))
|
||||
.collect(),
|
||||
};
|
||||
|
||||
self.counters.texture_views.add(1);
|
||||
|
||||
Ok(super::TextureView {
|
||||
raw,
|
||||
layers,
|
||||
attachment,
|
||||
view_format: desc.format,
|
||||
})
|
||||
}
|
||||
unsafe fn destroy_texture_view(&self, view: super::TextureView) {
|
||||
if !self.shared.private_caps.imageless_framebuffers {
|
||||
{
|
||||
let mut fbuf_lock = self.shared.framebuffers.lock();
|
||||
for (key, &raw_fbuf) in fbuf_lock.iter() {
|
||||
if key.attachments.iter().any(|at| at.raw == view.raw) {
|
||||
if key.attachments.iter().any(|at_view| *at_view == view.raw) {
|
||||
unsafe { self.shared.raw.destroy_framebuffer(raw_fbuf, None) };
|
||||
}
|
||||
}
|
||||
fbuf_lock.retain(|key, _| !key.attachments.iter().any(|at| at.raw == view.raw));
|
||||
fbuf_lock.retain(|key, _| !key.attachments.iter().any(|at_view| *at_view == view.raw));
|
||||
}
|
||||
unsafe { self.shared.raw.destroy_image_view(view.raw, None) };
|
||||
|
||||
@ -1855,7 +1762,7 @@ impl crate::Device for super::Device {
|
||||
|binding| {
|
||||
let layout = conv::derive_image_layout(
|
||||
binding.usage,
|
||||
binding.view.attachment.view_format,
|
||||
binding.view.view_format,
|
||||
);
|
||||
vk::DescriptorImageInfo::default()
|
||||
.image_view(binding.view.raw)
|
||||
@ -3177,6 +3084,4 @@ struct ImageWithoutMemory {
|
||||
raw: vk::Image,
|
||||
requirements: vk::MemoryRequirements,
|
||||
copy_size: crate::CopyExtent,
|
||||
view_formats: Vec<wgt::TextureFormat>,
|
||||
raw_flags: vk::ImageCreateFlags,
|
||||
}
|
||||
|
||||
@ -1108,16 +1108,6 @@ impl crate::Surface for super::Surface {
|
||||
return Err(crate::SurfaceError::Outdated);
|
||||
}
|
||||
|
||||
// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkRenderPassBeginInfo.html#VUID-VkRenderPassBeginInfo-framebuffer-03209
|
||||
let raw_flags = if swapchain
|
||||
.raw_flags
|
||||
.contains(vk::SwapchainCreateFlagsKHR::MUTABLE_FORMAT)
|
||||
{
|
||||
vk::ImageCreateFlags::MUTABLE_FORMAT | vk::ImageCreateFlags::EXTENDED_USAGE
|
||||
} else {
|
||||
vk::ImageCreateFlags::empty()
|
||||
};
|
||||
|
||||
let texture = super::SurfaceTexture {
|
||||
index,
|
||||
texture: super::Texture {
|
||||
@ -1125,15 +1115,12 @@ impl crate::Surface for super::Surface {
|
||||
drop_guard: None,
|
||||
block: None,
|
||||
external_memory: None,
|
||||
usage: swapchain.config.usage,
|
||||
format: swapchain.config.format,
|
||||
raw_flags,
|
||||
copy_size: crate::CopyExtent {
|
||||
width: swapchain.config.extent.width,
|
||||
height: swapchain.config.extent.height,
|
||||
depth: 1,
|
||||
},
|
||||
view_formats: swapchain.view_formats.clone(),
|
||||
},
|
||||
surface_semaphores: swapchain_semaphores_arc,
|
||||
};
|
||||
|
||||
@ -340,12 +340,10 @@ impl SwapchainImageSemaphores {
|
||||
|
||||
struct Swapchain {
|
||||
raw: vk::SwapchainKHR,
|
||||
raw_flags: vk::SwapchainCreateFlagsKHR,
|
||||
functor: khr::swapchain::Device,
|
||||
device: Arc<DeviceShared>,
|
||||
images: Vec<vk::Image>,
|
||||
config: crate::SurfaceConfiguration,
|
||||
view_formats: Vec<wgt::TextureFormat>,
|
||||
/// One wait semaphore per swapchain image. This will be associated with the
|
||||
/// surface texture, and later collected during submission.
|
||||
///
|
||||
@ -488,7 +486,6 @@ struct RayTracingDeviceExtensionFunctions {
|
||||
/// device geometry, but affect the code paths taken internally.
|
||||
#[derive(Clone, Debug)]
|
||||
struct PrivateCapabilities {
|
||||
imageless_framebuffers: bool,
|
||||
image_view_usage: bool,
|
||||
timeline_semaphores: bool,
|
||||
texture_d24: bool,
|
||||
@ -605,19 +602,9 @@ struct RenderPassKey {
|
||||
multiview: Option<NonZeroU32>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
struct FramebufferAttachment {
|
||||
/// Can be NULL if the framebuffer is image-less
|
||||
raw: vk::ImageView,
|
||||
raw_image_flags: vk::ImageCreateFlags,
|
||||
view_usage: wgt::TextureUses,
|
||||
view_format: wgt::TextureFormat,
|
||||
raw_view_formats: Vec<vk::Format>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, Hash, PartialEq)]
|
||||
struct FramebufferKey {
|
||||
attachments: ArrayVec<FramebufferAttachment, { MAX_TOTAL_ATTACHMENTS }>,
|
||||
attachments: ArrayVec<vk::ImageView, { MAX_TOTAL_ATTACHMENTS }>,
|
||||
extent: wgt::Extent3d,
|
||||
sample_count: u32,
|
||||
}
|
||||
@ -797,11 +784,8 @@ pub struct Texture {
|
||||
drop_guard: Option<crate::DropGuard>,
|
||||
external_memory: Option<vk::DeviceMemory>,
|
||||
block: Option<gpu_alloc::MemoryBlock<vk::DeviceMemory>>,
|
||||
usage: wgt::TextureUses,
|
||||
format: wgt::TextureFormat,
|
||||
raw_flags: vk::ImageCreateFlags,
|
||||
copy_size: crate::CopyExtent,
|
||||
view_formats: Vec<wgt::TextureFormat>,
|
||||
}
|
||||
|
||||
impl crate::DynTexture for Texture {}
|
||||
@ -819,7 +803,7 @@ impl Texture {
|
||||
pub struct TextureView {
|
||||
raw: vk::ImageView,
|
||||
layers: NonZeroU32,
|
||||
attachment: FramebufferAttachment,
|
||||
view_format: wgt::TextureFormat,
|
||||
}
|
||||
|
||||
impl crate::DynTextureView for TextureView {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user