mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 00:03:29 +00:00
Add out multiple tests of vertex pulling
This commit is contained in:
parent
528a311dd1
commit
3d8a4baeb8
@ -2,9 +2,7 @@
|
||||
|
||||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
|
||||
use wgt::{
|
||||
BackendBit, DeviceDescriptor, DownlevelProperties, Features, Limits,
|
||||
};
|
||||
use wgt::{BackendBit, DeviceDescriptor, DownlevelProperties, Features, Limits};
|
||||
|
||||
use wgpu::{util, Adapter, Device, Instance, Queue};
|
||||
|
||||
@ -101,28 +99,38 @@ impl Default for TestParameters {
|
||||
// Builder pattern to make it easier
|
||||
#[allow(dead_code)]
|
||||
impl TestParameters {
|
||||
/// Set of common features that most tests require.
|
||||
pub fn test_features(self) -> Self {
|
||||
self.features(Features::MAPPABLE_PRIMARY_BUFFERS | Features::VERTEX_WRITABLE_STORAGE)
|
||||
}
|
||||
|
||||
pub fn features(mut self, features: Features) -> Self {
|
||||
self.required_features |= features;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn backend_failures(mut self, backends: BackendBit) -> Self {
|
||||
self.backend_failures |= backends;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn failure(mut self) -> Self {
|
||||
self.always_failure = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn initialize_test(
|
||||
parameters: TestParameters,
|
||||
test_function: impl FnOnce(TestingContext),
|
||||
) {
|
||||
// We don't actually care if it fails
|
||||
let _ = env_logger::try_init();
|
||||
pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(TestingContext)) {
|
||||
// We don't actually care if it fails
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
let backend_bits = util::backend_bits_from_env().unwrap_or(BackendBit::all());
|
||||
let instance = Instance::new(backend_bits);
|
||||
let adapter = pollster::block_on(util::initialize_adapter_from_env_or_default(&instance, backend_bits))
|
||||
.expect("could not find sutable adapter on the system");
|
||||
let adapter = pollster::block_on(util::initialize_adapter_from_env_or_default(
|
||||
&instance,
|
||||
backend_bits,
|
||||
))
|
||||
.expect("could not find sutable adapter on the system");
|
||||
|
||||
let adapter_info = adapter.get_info();
|
||||
let adapter_lowercase_name = adapter_info.name.to_lowercase();
|
||||
|
@ -8,7 +8,8 @@ var<storage> indices: [[access(read_write)]] Indices;
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vs_main([[builtin(instance_index)]] instance: u32, [[builtin(vertex_index)]] index: u32) -> [[builtin(position)]] vec4<f32> {
|
||||
indices.arr[index] = instance;
|
||||
let idx = instance * 3u + index;
|
||||
indices.arr[idx] = idx;
|
||||
return vec4<f32>(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
@ -2,135 +2,177 @@ use std::num::NonZeroU64;
|
||||
|
||||
use wgpu::util::DeviceExt;
|
||||
|
||||
use crate::common::{initialize_test, TestParameters};
|
||||
use crate::common::{initialize_test, TestParameters, TestingContext};
|
||||
|
||||
fn pulling_common(
|
||||
ctx: TestingContext,
|
||||
expected: &[u32],
|
||||
function: impl FnOnce(&mut wgpu::RenderPass<'_>),
|
||||
) {
|
||||
let shader = ctx
|
||||
.device
|
||||
.create_shader_module(&wgpu::include_wgsl!("draw.vert.wgsl"));
|
||||
|
||||
let bgl = ctx
|
||||
.device
|
||||
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
ty: wgpu::BindingType::Buffer {
|
||||
ty: wgpu::BufferBindingType::Storage { read_only: false },
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: NonZeroU64::new(4),
|
||||
},
|
||||
visibility: wgpu::ShaderStage::VERTEX,
|
||||
count: None,
|
||||
}],
|
||||
});
|
||||
|
||||
let buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
size: 4 * expected.len() as u64,
|
||||
usage: wgpu::BufferUsage::COPY_SRC
|
||||
| wgpu::BufferUsage::STORAGE
|
||||
| wgpu::BufferUsage::MAP_READ,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
let bg = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: None,
|
||||
layout: &bgl,
|
||||
entries: &[wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: buffer.as_entire_binding(),
|
||||
}],
|
||||
});
|
||||
|
||||
let ppl = ctx
|
||||
.device
|
||||
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: None,
|
||||
bind_group_layouts: &[&bgl],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
let pipeline = ctx
|
||||
.device
|
||||
.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: None,
|
||||
layout: Some(&ppl),
|
||||
vertex: wgpu::VertexState {
|
||||
buffers: &[],
|
||||
entry_point: "vs_main",
|
||||
module: &shader,
|
||||
},
|
||||
primitive: wgpu::PrimitiveState::default(),
|
||||
depth_stencil: None,
|
||||
multisample: wgpu::MultisampleState::default(),
|
||||
fragment: Some(wgpu::FragmentState {
|
||||
entry_point: "fs_main",
|
||||
module: &shader,
|
||||
targets: &[wgpu::ColorTargetState {
|
||||
format: wgpu::TextureFormat::Rgba8Unorm,
|
||||
blend: None,
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
}],
|
||||
}),
|
||||
});
|
||||
|
||||
let dummy = ctx
|
||||
.device
|
||||
.create_texture_with_data(
|
||||
&ctx.queue,
|
||||
&wgpu::TextureDescriptor {
|
||||
label: Some("dummy"),
|
||||
size: wgpu::Extent3d {
|
||||
width: 1,
|
||||
height: 1,
|
||||
depth_or_array_layers: 1,
|
||||
},
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8Unorm,
|
||||
usage: wgpu::TextureUsage::RENDER_ATTACHMENT | wgpu::TextureUsage::COPY_DST,
|
||||
},
|
||||
&[0, 0, 0, 1],
|
||||
)
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
|
||||
let mut encoder = ctx
|
||||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor::default());
|
||||
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[wgpu::RenderPassColorAttachment {
|
||||
ops: wgpu::Operations::default(),
|
||||
resolve_target: None,
|
||||
view: &dummy,
|
||||
}],
|
||||
depth_stencil_attachment: None,
|
||||
label: None,
|
||||
});
|
||||
|
||||
rpass.set_pipeline(&pipeline);
|
||||
rpass.set_bind_group(0, &bg, &[]);
|
||||
function(&mut rpass);
|
||||
|
||||
drop(rpass);
|
||||
|
||||
ctx.queue.submit(Some(encoder.finish()));
|
||||
let slice = buffer.slice(..);
|
||||
let _ = slice.map_async(wgpu::MapMode::Read);
|
||||
ctx.device.poll(wgpu::Maintain::Wait);
|
||||
let data: Vec<u32> = bytemuck::cast_slice(&*slice.get_mapped_range()).to_vec();
|
||||
|
||||
assert_eq!(data, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn draw() {
|
||||
initialize_test(TestParameters::default().test_features(), |ctx| {
|
||||
pulling_common(ctx, &[0, 1, 2, 3, 4, 5], |cmb| {
|
||||
cmb.draw(0..6, 0..1);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn draw_vertex_offset() {
|
||||
initialize_test(
|
||||
TestParameters::default()
|
||||
.features(
|
||||
wgpu::Features::VERTEX_WRITABLE_STORAGE | wgpu::Features::MAPPABLE_PRIMARY_BUFFERS,
|
||||
)
|
||||
.failure(),
|
||||
.test_features()
|
||||
.backend_failures(wgpu::BackendBit::DX12 | wgpu::BackendBit::DX11),
|
||||
|ctx| {
|
||||
let shader = ctx
|
||||
.device
|
||||
.create_shader_module(&wgpu::include_wgsl!("draw.vert.wgsl"));
|
||||
|
||||
let bgl = ctx
|
||||
.device
|
||||
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
ty: wgpu::BindingType::Buffer {
|
||||
ty: wgpu::BufferBindingType::Storage { read_only: false },
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: NonZeroU64::new(4),
|
||||
},
|
||||
visibility: wgpu::ShaderStage::VERTEX,
|
||||
count: None,
|
||||
}],
|
||||
});
|
||||
|
||||
let buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
size: 4 * 6,
|
||||
usage: wgpu::BufferUsage::COPY_SRC
|
||||
| wgpu::BufferUsage::STORAGE
|
||||
| wgpu::BufferUsage::MAP_READ,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
let bg = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: None,
|
||||
layout: &bgl,
|
||||
entries: &[wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: buffer.as_entire_binding(),
|
||||
}],
|
||||
});
|
||||
|
||||
let ppl = ctx
|
||||
.device
|
||||
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: None,
|
||||
bind_group_layouts: &[&bgl],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
let pipeline = ctx
|
||||
.device
|
||||
.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: None,
|
||||
layout: Some(&ppl),
|
||||
vertex: wgpu::VertexState {
|
||||
buffers: &[],
|
||||
entry_point: "vs_main",
|
||||
module: &shader,
|
||||
},
|
||||
primitive: wgpu::PrimitiveState::default(),
|
||||
depth_stencil: None,
|
||||
multisample: wgpu::MultisampleState::default(),
|
||||
fragment: Some(wgpu::FragmentState {
|
||||
entry_point: "fs_main",
|
||||
module: &shader,
|
||||
targets: &[wgpu::ColorTargetState {
|
||||
format: wgpu::TextureFormat::Rgba8Unorm,
|
||||
blend: None,
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
}],
|
||||
}),
|
||||
});
|
||||
|
||||
let dummy = ctx
|
||||
.device
|
||||
.create_texture_with_data(
|
||||
&ctx.queue,
|
||||
&wgpu::TextureDescriptor {
|
||||
label: Some("dummy"),
|
||||
size: wgpu::Extent3d {
|
||||
width: 1,
|
||||
height: 1,
|
||||
depth_or_array_layers: 1,
|
||||
},
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8Unorm,
|
||||
usage: wgpu::TextureUsage::RENDER_ATTACHMENT | wgpu::TextureUsage::COPY_DST,
|
||||
},
|
||||
&[0, 0, 0, 1],
|
||||
)
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
|
||||
let mut encoder = ctx
|
||||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor::default());
|
||||
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[wgpu::RenderPassColorAttachment {
|
||||
ops: wgpu::Operations::default(),
|
||||
resolve_target: None,
|
||||
view: &dummy,
|
||||
}],
|
||||
depth_stencil_attachment: None,
|
||||
label: None,
|
||||
});
|
||||
|
||||
rpass.set_pipeline(&pipeline);
|
||||
rpass.set_bind_group(0, &bg, &[]);
|
||||
rpass.draw(0..6, 0..1);
|
||||
|
||||
drop(rpass);
|
||||
|
||||
ctx.queue.submit(Some(encoder.finish()));
|
||||
let slice = buffer.slice(..);
|
||||
let _ = slice.map_async(wgpu::MapMode::Read);
|
||||
ctx.device.poll(wgpu::Maintain::Wait);
|
||||
let data: Vec<u32> = bytemuck::cast_slice(&*slice.get_mapped_range()).to_vec();
|
||||
|
||||
assert_eq!(data, [0, 1, 2, 3, 4, 5]);
|
||||
pulling_common(ctx, &[0, 1, 2, 3, 4, 5], |cmb| {
|
||||
cmb.draw(0..3, 0..1);
|
||||
cmb.draw(3..6, 0..1);
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn draw_instanced() {
|
||||
initialize_test(TestParameters::default().test_features(), |ctx| {
|
||||
pulling_common(ctx, &[0, 1, 2, 3, 4, 5], |cmb| {
|
||||
cmb.draw(0..3, 0..2);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn draw_instanced_offset() {
|
||||
initialize_test(
|
||||
TestParameters::default()
|
||||
.test_features()
|
||||
.backend_failures(wgpu::BackendBit::DX12 | wgpu::BackendBit::DX11),
|
||||
|ctx| {
|
||||
pulling_common(ctx, &[0, 1, 2, 3, 4, 5], |cmb| {
|
||||
cmb.draw(0..3, 0..1);
|
||||
cmb.draw(0..3, 1..2);
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user