mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
127 lines
5.1 KiB
Rust
127 lines
5.1 KiB
Rust
use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters};
|
|
|
|
#[gpu_test]
|
|
static OCCLUSION_QUERY: GpuTestConfiguration = GpuTestConfiguration::new()
|
|
.parameters(TestParameters::default().expect_fail(FailureCase::webgl2()))
|
|
.run_async(|ctx| async move {
|
|
// Create depth texture
|
|
let depth_texture = ctx.device.create_texture(&wgpu::TextureDescriptor {
|
|
label: Some("Depth texture"),
|
|
size: wgpu::Extent3d {
|
|
width: 64,
|
|
height: 64,
|
|
depth_or_array_layers: 1,
|
|
},
|
|
mip_level_count: 1,
|
|
sample_count: 1,
|
|
dimension: wgpu::TextureDimension::D2,
|
|
format: wgpu::TextureFormat::Depth32Float,
|
|
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
|
view_formats: &[],
|
|
});
|
|
let depth_texture_view = depth_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
|
|
|
// Setup pipeline using a simple shader with hardcoded vertices
|
|
let shader = ctx
|
|
.device
|
|
.create_shader_module(wgpu::include_wgsl!("shader.wgsl"));
|
|
let pipeline = ctx
|
|
.device
|
|
.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
|
label: Some("Pipeline"),
|
|
layout: None,
|
|
vertex: wgpu::VertexState {
|
|
module: &shader,
|
|
entry_point: Some("vs_main"),
|
|
compilation_options: Default::default(),
|
|
buffers: &[],
|
|
},
|
|
fragment: None,
|
|
primitive: wgpu::PrimitiveState::default(),
|
|
depth_stencil: Some(wgpu::DepthStencilState {
|
|
format: wgpu::TextureFormat::Depth32Float,
|
|
depth_write_enabled: true,
|
|
depth_compare: wgpu::CompareFunction::Less,
|
|
stencil: wgpu::StencilState::default(),
|
|
bias: wgpu::DepthBiasState::default(),
|
|
}),
|
|
multisample: wgpu::MultisampleState::default(),
|
|
multiview: None,
|
|
cache: None,
|
|
});
|
|
|
|
// Create occlusion query set
|
|
let query_set = ctx.device.create_query_set(&wgpu::QuerySetDescriptor {
|
|
label: Some("Query set"),
|
|
ty: wgpu::QueryType::Occlusion,
|
|
count: 3,
|
|
});
|
|
|
|
let mut encoder = ctx
|
|
.device
|
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor::default());
|
|
{
|
|
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
|
label: Some("Render pass"),
|
|
color_attachments: &[],
|
|
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
|
|
view: &depth_texture_view,
|
|
depth_ops: Some(wgpu::Operations {
|
|
load: wgpu::LoadOp::Clear(1.0),
|
|
store: wgpu::StoreOp::Store,
|
|
}),
|
|
stencil_ops: None,
|
|
}),
|
|
timestamp_writes: None,
|
|
occlusion_query_set: Some(&query_set),
|
|
});
|
|
render_pass.set_pipeline(&pipeline);
|
|
|
|
// Not occluded (z = 1.0, nothing drawn yet)
|
|
render_pass.begin_occlusion_query(0);
|
|
render_pass.draw(4..7, 0..1);
|
|
render_pass.end_occlusion_query();
|
|
|
|
// Not occluded (z = 0.0)
|
|
render_pass.begin_occlusion_query(1);
|
|
render_pass.draw(0..3, 0..1);
|
|
render_pass.end_occlusion_query();
|
|
|
|
// Occluded (z = 1.0)
|
|
render_pass.begin_occlusion_query(2);
|
|
render_pass.draw(4..7, 0..1);
|
|
render_pass.end_occlusion_query();
|
|
}
|
|
|
|
// Resolve query set to buffer
|
|
let query_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor {
|
|
label: Some("Query buffer"),
|
|
size: size_of::<u64>() as u64 * 3,
|
|
usage: wgpu::BufferUsages::QUERY_RESOLVE | wgpu::BufferUsages::COPY_SRC,
|
|
mapped_at_creation: false,
|
|
});
|
|
encoder.resolve_query_set(&query_set, 0..3, &query_buffer, 0);
|
|
|
|
let mapping_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor {
|
|
label: Some("Mapping buffer"),
|
|
size: query_buffer.size(),
|
|
usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST,
|
|
mapped_at_creation: false,
|
|
});
|
|
encoder.copy_buffer_to_buffer(&query_buffer, 0, &mapping_buffer, 0, query_buffer.size());
|
|
|
|
ctx.queue.submit(Some(encoder.finish()));
|
|
|
|
mapping_buffer
|
|
.slice(..)
|
|
.map_async(wgpu::MapMode::Read, |_| ());
|
|
ctx.async_poll(wgpu::PollType::wait()).await.unwrap();
|
|
let query_buffer_view = mapping_buffer.slice(..).get_mapped_range();
|
|
let query_data: &[u64; 3] = bytemuck::from_bytes(&query_buffer_view);
|
|
|
|
// WebGPU only defines query results as zero/non-zero
|
|
assert_ne!(query_data[0], 0);
|
|
assert_ne!(query_data[1], 0);
|
|
assert_eq!(query_data[2], 0);
|
|
});
|