mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
[vk] add support for rendering to slices of 3D textures
This commit is contained in:
parent
f728a92366
commit
d14849df48
@ -2,7 +2,7 @@ use wgpu::{
|
||||
util::{BufferInitDescriptor, DeviceExt},
|
||||
vertex_attr_array,
|
||||
};
|
||||
use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext};
|
||||
use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext};
|
||||
|
||||
#[gpu_test]
|
||||
static DRAW_TO_2D_VIEW: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
@ -236,14 +236,10 @@ async fn run_test(
|
||||
|
||||
#[gpu_test]
|
||||
static DRAW_TO_3D_VIEW: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(
|
||||
TestParameters::default()
|
||||
.limits(wgpu::Limits {
|
||||
max_texture_dimension_3d: 512,
|
||||
..wgpu::Limits::downlevel_webgl2_defaults()
|
||||
})
|
||||
.skip(FailureCase::backend(wgpu::Backends::VULKAN)),
|
||||
)
|
||||
.parameters(TestParameters::default().limits(wgpu::Limits {
|
||||
max_texture_dimension_3d: 512,
|
||||
..wgpu::Limits::downlevel_webgl2_defaults()
|
||||
}))
|
||||
.run_async(run_test_3d);
|
||||
|
||||
async fn run_test_3d(ctx: TestingContext) {
|
||||
|
||||
@ -929,16 +929,6 @@ impl Device {
|
||||
desc.format,
|
||||
));
|
||||
}
|
||||
|
||||
// Renderable textures can only be 2D on Vulkan (until we implement 3D support)
|
||||
if self.backend() == wgt::Backend::Vulkan
|
||||
&& desc.usage.contains(wgt::TextureUsages::RENDER_ATTACHMENT)
|
||||
{
|
||||
return Err(CreateTextureError::InvalidDimensionUsages(
|
||||
wgt::TextureUsages::RENDER_ATTACHMENT,
|
||||
desc.dimension,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if desc.dimension != wgt::TextureDimension::D2
|
||||
|
||||
@ -71,6 +71,31 @@ impl super::CommandEncoder {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn make_temp_texture_view(
|
||||
&mut self,
|
||||
key: super::TempTextureViewKey,
|
||||
) -> Result<vk::ImageView, crate::DeviceError> {
|
||||
Ok(match self.temp_texture_views.entry(key) {
|
||||
Entry::Occupied(e) => *e.get(),
|
||||
Entry::Vacant(e) => {
|
||||
let vk_info = vk::ImageViewCreateInfo::default()
|
||||
.image(e.key().texture)
|
||||
.view_type(vk::ImageViewType::TYPE_2D)
|
||||
.format(e.key().format)
|
||||
.subresource_range(vk::ImageSubresourceRange {
|
||||
aspect_mask: vk::ImageAspectFlags::COLOR,
|
||||
base_mip_level: e.key().mip_level,
|
||||
level_count: 1,
|
||||
base_array_layer: e.key().depth_slice,
|
||||
layer_count: 1,
|
||||
});
|
||||
let raw = unsafe { self.device.raw.create_image_view(&vk_info, None) }
|
||||
.map_err(super::map_host_device_oom_and_ioca_err)?;
|
||||
*e.insert(raw)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::CommandEncoder for super::CommandEncoder {
|
||||
@ -747,6 +772,18 @@ impl crate::CommandEncoder for super::CommandEncoder {
|
||||
|
||||
for cat in desc.color_attachments {
|
||||
if let Some(cat) = cat.as_ref() {
|
||||
let color_view = if cat.target.view.dimension == wgt::TextureViewDimension::D3 {
|
||||
let key = super::TempTextureViewKey {
|
||||
texture: cat.target.view.raw_texture,
|
||||
format: cat.target.view.raw_format,
|
||||
mip_level: cat.target.view.base_mip_level,
|
||||
depth_slice: cat.depth_slice.unwrap(),
|
||||
};
|
||||
self.make_temp_texture_view(key)?
|
||||
} else {
|
||||
cat.target.view.raw
|
||||
};
|
||||
|
||||
vk_clear_values.push(vk::ClearValue {
|
||||
color: unsafe { cat.make_vk_clear_color() },
|
||||
});
|
||||
@ -759,7 +796,7 @@ impl crate::CommandEncoder for super::CommandEncoder {
|
||||
};
|
||||
|
||||
rp_key.colors.push(Some(color));
|
||||
fb_key.attachments.push(cat.target.view.raw);
|
||||
fb_key.attachments.push(color_view);
|
||||
if let Some(ref at) = cat.resolve_target {
|
||||
vk_clear_values.push(unsafe { mem::zeroed() });
|
||||
fb_key.attachments.push(at.view.raw);
|
||||
|
||||
@ -640,6 +640,11 @@ impl super::Device {
|
||||
let copy_size = desc.copy_extent();
|
||||
|
||||
let mut raw_flags = vk::ImageCreateFlags::empty();
|
||||
if desc.dimension == wgt::TextureDimension::D3
|
||||
&& desc.usage.contains(wgt::TextureUses::COLOR_TARGET)
|
||||
{
|
||||
raw_flags |= vk::ImageCreateFlags::TYPE_2D_ARRAY_COMPATIBLE;
|
||||
}
|
||||
if desc.is_cube_compatible() {
|
||||
raw_flags |= vk::ImageCreateFlags::CUBE_COMPATIBLE;
|
||||
}
|
||||
@ -1287,10 +1292,13 @@ impl crate::Device for super::Device {
|
||||
self.counters.texture_views.add(1);
|
||||
|
||||
Ok(super::TextureView {
|
||||
raw_texture: texture.raw,
|
||||
raw,
|
||||
layers,
|
||||
format: desc.format,
|
||||
raw_format,
|
||||
base_mip_level: desc.range.base_mip_level,
|
||||
dimension: desc.dimension,
|
||||
})
|
||||
}
|
||||
unsafe fn destroy_texture_view(&self, view: super::TextureView) {
|
||||
@ -1387,6 +1395,7 @@ impl crate::Device for super::Device {
|
||||
rpass_debug_marker_active: false,
|
||||
end_of_pass_timer_query: None,
|
||||
framebuffers: Default::default(),
|
||||
temp_texture_views: Default::default(),
|
||||
counters: Arc::clone(&self.counters),
|
||||
})
|
||||
}
|
||||
|
||||
@ -790,10 +790,13 @@ impl Texture {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TextureView {
|
||||
raw_texture: vk::Image,
|
||||
raw: vk::ImageView,
|
||||
layers: NonZeroU32,
|
||||
format: wgt::TextureFormat,
|
||||
raw_format: vk::Format,
|
||||
base_mip_level: u32,
|
||||
dimension: wgt::TextureViewDimension,
|
||||
}
|
||||
|
||||
impl crate::DynTextureView for TextureView {}
|
||||
@ -871,6 +874,14 @@ struct FramebufferKey {
|
||||
extent: wgt::Extent3d,
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, Hash, PartialEq)]
|
||||
struct TempTextureViewKey {
|
||||
texture: vk::Image,
|
||||
format: vk::Format,
|
||||
mip_level: u32,
|
||||
depth_slice: u32,
|
||||
}
|
||||
|
||||
pub struct CommandEncoder {
|
||||
raw: vk::CommandPool,
|
||||
device: Arc<DeviceShared>,
|
||||
@ -908,6 +919,7 @@ pub struct CommandEncoder {
|
||||
end_of_pass_timer_query: Option<(vk::QueryPool, u32)>,
|
||||
|
||||
framebuffers: FastHashMap<FramebufferKey, vk::Framebuffer>,
|
||||
temp_texture_views: FastHashMap<TempTextureViewKey, vk::ImageView>,
|
||||
|
||||
counters: Arc<wgt::HalCounters>,
|
||||
}
|
||||
@ -935,6 +947,10 @@ impl Drop for CommandEncoder {
|
||||
unsafe { self.device.raw.destroy_framebuffer(fb, None) };
|
||||
}
|
||||
|
||||
for (_, view) in self.temp_texture_views.drain() {
|
||||
unsafe { self.device.raw.destroy_image_view(view, None) };
|
||||
}
|
||||
|
||||
self.counters.command_encoders.sub(1);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user