Render bundle support, use in msaa-line example

This commit is contained in:
Dzmitry Malyshau
2020-06-09 10:47:49 -04:00
parent 7b887f12a3
commit 71cfb32342
5 changed files with 571 additions and 191 deletions

View File

@@ -28,14 +28,14 @@ vulkan = ["wgc/gfx-backend-vulkan"]
package = "wgpu-core"
version = "0.5"
git = "https://github.com/gfx-rs/wgpu"
rev = "64ae59072db443eb1e47ee14d77370eec9f4b012"
rev = "b0b99d89b71894cf01d8c938aae87b2348edeb5b"
features = ["raw-window-handle"]
[dependencies.wgt]
package = "wgpu-types"
version = "0.5"
git = "https://github.com/gfx-rs/wgpu"
rev = "64ae59072db443eb1e47ee14d77370eec9f4b012"
rev = "b0b99d89b71894cf01d8c938aae87b2348edeb5b"
[dependencies]
arrayvec = "0.5"

View File

@@ -10,6 +10,8 @@
#[path = "../framework.rs"]
mod framework;
use std::iter;
use bytemuck::{Pod, Zeroable};
use wgpu::vertex_attr_array;
@@ -25,29 +27,31 @@ unsafe impl Pod for Vertex {}
unsafe impl Zeroable for Vertex {}
struct Example {
bundle: wgpu::RenderBundle,
vs_module: wgpu::ShaderModule,
fs_module: wgpu::ShaderModule,
pipeline_layout: wgpu::PipelineLayout,
pipeline: wgpu::RenderPipeline,
multisampled_framebuffer: wgpu::TextureView,
vertex_buffer: wgpu::Buffer,
vertex_count: u32,
rebuild_pipeline: bool,
sample_count: u32,
rebuild_bundle: bool,
sc_desc: wgpu::SwapChainDescriptor,
}
impl Example {
fn create_pipeline(
fn create_bundle(
device: &wgpu::Device,
sc_desc: &wgpu::SwapChainDescriptor,
vs_module: &wgpu::ShaderModule,
fs_module: &wgpu::ShaderModule,
pipeline_layout: &wgpu::PipelineLayout,
sample_count: u32,
) -> wgpu::RenderPipeline {
vertex_buffer: &wgpu::Buffer,
vertex_count: u32,
) -> wgpu::RenderBundle {
log::info!("sample_count: {}", sample_count);
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
layout: &pipeline_layout,
vertex_stage: wgpu::ProgrammableStageDescriptor {
module: vs_module,
@@ -83,6 +87,19 @@ impl Example {
sample_count,
sample_mask: !0,
alpha_to_coverage_enabled: false,
});
let mut encoder =
device.create_render_bundle_encoder(&wgpu::RenderBundleEncoderDescriptor {
label: None,
color_formats: &[sc_desc.format],
depth_stencil_format: None,
sample_count,
});
encoder.set_pipeline(&pipeline);
encoder.set_vertex_buffer(0, vertex_buffer.slice(..));
encoder.draw(0..vertex_count, 0..1);
encoder.finish(&wgpu::RenderBundleDescriptor {
label: Some("main"),
})
}
@@ -132,14 +149,6 @@ impl framework::Example for Example {
bind_group_layouts: &[],
});
let pipeline = Example::create_pipeline(
device,
&sc_desc,
&vs_module,
&fs_module,
&pipeline_layout,
sample_count,
);
let multisampled_framebuffer =
Example::create_multisampled_framebuffer(device, sc_desc, sample_count);
@@ -165,16 +174,27 @@ impl framework::Example for Example {
);
let vertex_count = vertex_data.len() as u32;
let bundle = Example::create_bundle(
device,
&sc_desc,
&vs_module,
&fs_module,
&pipeline_layout,
sample_count,
&vertex_buffer,
vertex_count,
);
let this = Example {
bundle,
vs_module,
fs_module,
pipeline_layout,
pipeline,
multisampled_framebuffer,
vertex_buffer,
vertex_count,
rebuild_pipeline: false,
sample_count,
rebuild_bundle: false,
sc_desc: sc_desc.clone(),
};
(this, None)
@@ -188,13 +208,13 @@ impl framework::Example for Example {
Some(winit::event::VirtualKeyCode::Left) => {
if self.sample_count >= 2 {
self.sample_count = self.sample_count >> 1;
self.rebuild_pipeline = true;
self.rebuild_bundle = true;
}
}
Some(winit::event::VirtualKeyCode::Right) => {
if self.sample_count <= 16 {
self.sample_count = self.sample_count << 1;
self.rebuild_pipeline = true;
self.rebuild_bundle = true;
}
}
_ => {}
@@ -222,18 +242,20 @@ impl framework::Example for Example {
device: &wgpu::Device,
_queue: &wgpu::Queue,
) -> wgpu::CommandBuffer {
if self.rebuild_pipeline {
self.pipeline = Example::create_pipeline(
if self.rebuild_bundle {
self.bundle = Example::create_bundle(
device,
&self.sc_desc,
&self.vs_module,
&self.fs_module,
&self.pipeline_layout,
self.sample_count,
&self.vertex_buffer,
self.vertex_count,
);
self.multisampled_framebuffer =
Example::create_multisampled_framebuffer(device, &self.sc_desc, self.sample_count);
self.rebuild_pipeline = false;
self.rebuild_bundle = false;
}
let mut encoder =
@@ -257,13 +279,12 @@ impl framework::Example for Example {
}
};
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[rpass_color_attachment],
depth_stencil_attachment: None,
});
rpass.set_pipeline(&self.pipeline);
rpass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
rpass.draw(0..self.vertex_count, 0..1);
encoder
.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[rpass_color_attachment],
depth_stencil_attachment: None,
})
.execute_bundles(iter::once(&self.bundle));
}
encoder.finish()

View File

@@ -31,10 +31,11 @@ pub type Context = wgc::hub::Global<wgc::hub::IdentityManagerFactory>;
mod pass_impl {
use super::Context;
use smallvec::SmallVec;
use std::ops::Range;
use wgc::command::{compute_ffi::*, render_ffi::*};
use wgc::command::{bundle_ffi::*, compute_ffi::*, render_ffi::*};
impl crate::ComputePassInner<Context> for wgc::command::RawPass {
impl crate::ComputePassInner<Context> for wgc::command::RawPass<wgc::id::CommandEncoderId> {
fn set_pipeline(&mut self, pipeline: &wgc::id::ComputePipelineId) {
unsafe { wgpu_compute_pass_set_pipeline(self, *pipeline) }
}
@@ -66,7 +67,7 @@ mod pass_impl {
}
}
impl crate::RenderPassInner<Context> for wgc::command::RawPass {
impl crate::RenderInner<Context> for wgc::command::RawPass<wgc::id::CommandEncoderId> {
fn set_pipeline(&mut self, pipeline: &wgc::id::RenderPipelineId) {
unsafe { wgpu_render_pass_set_pipeline(self, *pipeline) }
}
@@ -103,28 +104,6 @@ mod pass_impl {
) {
unsafe { wgpu_render_pass_set_vertex_buffer(self, slot, *buffer, offset, size) }
}
fn set_blend_color(&mut self, color: wgt::Color) {
unsafe { wgpu_render_pass_set_blend_color(self, &color) }
}
fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32) {
unsafe { wgpu_render_pass_set_scissor_rect(self, x, y, width, height) }
}
fn set_viewport(
&mut self,
x: f32,
y: f32,
width: f32,
height: f32,
min_depth: f32,
max_depth: f32,
) {
unsafe {
wgpu_render_pass_set_viewport(self, x, y, width, height, min_depth, max_depth)
}
}
fn set_stencil_reference(&mut self, reference: u32) {
unsafe { wgpu_render_pass_set_stencil_reference(self, reference) }
}
fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
unsafe {
wgpu_render_pass_draw(
@@ -165,6 +144,123 @@ mod pass_impl {
}
}
}
impl crate::RenderPassInner<Context> for wgc::command::RawPass<wgc::id::CommandEncoderId> {
fn set_blend_color(&mut self, color: wgt::Color) {
unsafe { wgpu_render_pass_set_blend_color(self, &color) }
}
fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32) {
unsafe { wgpu_render_pass_set_scissor_rect(self, x, y, width, height) }
}
fn set_viewport(
&mut self,
x: f32,
y: f32,
width: f32,
height: f32,
min_depth: f32,
max_depth: f32,
) {
unsafe {
wgpu_render_pass_set_viewport(self, x, y, width, height, min_depth, max_depth)
}
}
fn set_stencil_reference(&mut self, reference: u32) {
unsafe { wgpu_render_pass_set_stencil_reference(self, reference) }
}
fn execute_bundles<'a, I: Iterator<Item = &'a wgc::id::RenderBundleId>>(
&mut self,
render_bundles: I,
) {
let temp_render_bundles = render_bundles.cloned().collect::<SmallVec<[_; 4]>>();
unsafe {
wgpu_render_pass_execute_bundles(
self,
temp_render_bundles.as_ptr(),
temp_render_bundles.len(),
)
}
}
}
impl crate::RenderInner<Context> for wgc::command::RenderBundleEncoder {
fn set_pipeline(&mut self, pipeline: &wgc::id::RenderPipelineId) {
unsafe { wgpu_render_bundle_set_pipeline(self, *pipeline) }
}
fn set_bind_group(
&mut self,
index: u32,
bind_group: &wgc::id::BindGroupId,
offsets: &[wgt::DynamicOffset],
) {
unsafe {
wgpu_render_bundle_set_bind_group(
self,
index,
*bind_group,
offsets.as_ptr(),
offsets.len(),
)
}
}
fn set_index_buffer(
&mut self,
buffer: &wgc::id::BufferId,
offset: wgt::BufferAddress,
size: wgt::BufferSize,
) {
unsafe { wgpu_render_bundle_set_index_buffer(self, *buffer, offset, size) }
}
fn set_vertex_buffer(
&mut self,
slot: u32,
buffer: &wgc::id::BufferId,
offset: wgt::BufferAddress,
size: wgt::BufferSize,
) {
unsafe { wgpu_render_bundle_set_vertex_buffer(self, slot, *buffer, offset, size) }
}
fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
unsafe {
wgpu_render_bundle_draw(
self,
vertices.end - vertices.start,
instances.end - instances.start,
vertices.start,
instances.start,
)
}
}
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
unsafe {
wgpu_render_bundle_draw_indexed(
self,
indices.end - indices.start,
instances.end - instances.start,
indices.start,
base_vertex,
instances.start,
)
}
}
fn draw_indirect(
&mut self,
indirect_buffer: &wgc::id::BufferId,
indirect_offset: wgt::BufferAddress,
) {
unsafe { wgpu_render_bundle_draw_indirect(self, *indirect_buffer, indirect_offset) }
}
fn draw_indexed_indirect(
&mut self,
indirect_buffer: &wgc::id::BufferId,
indirect_offset: wgt::BufferAddress,
) {
unsafe {
wgpu_render_pass_bundle_indexed_indirect(self, *indirect_buffer, indirect_offset)
}
}
}
}
fn map_buffer_copy_view(view: crate::BufferCopyView) -> wgc::command::BufferCopyView {
@@ -197,11 +293,13 @@ impl crate::Context for Context {
type RenderPipelineId = wgc::id::RenderPipelineId;
type ComputePipelineId = wgc::id::ComputePipelineId;
type CommandEncoderId = wgc::id::CommandEncoderId;
type ComputePassId = wgc::command::RawPass;
type ComputePassId = wgc::command::RawPass<wgc::id::CommandEncoderId>;
type RenderPassId = wgc::command::RawPass<wgc::id::CommandEncoderId>;
type CommandBufferId = wgc::id::CommandBufferId;
type RenderBundleEncoderId = wgc::command::RenderBundleEncoder;
type RenderBundleId = wgc::id::RenderBundleId;
type SurfaceId = wgc::id::SurfaceId;
type SwapChainId = wgc::id::SwapChainId;
type RenderPassId = wgc::command::RawPass;
type SwapChainOutputDetail = SwapChainOutputDetail;
@@ -518,6 +616,14 @@ impl crate::Context for Context {
))
}
fn device_create_render_bundle_encoder(
&self,
device: &Self::DeviceId,
desc: &wgt::RenderBundleEncoderDescriptor,
) -> Self::RenderBundleEncoderId {
wgc::command::RenderBundleEncoder::new(desc, *device)
}
fn device_drop(&self, device: &Self::DeviceId) {
#[cfg(not(target_arch = "wasm32"))]
gfx_select!(*device => self.device_poll(*device, true));
@@ -663,6 +769,9 @@ impl crate::Context for Context {
fn command_buffer_drop(&self, command_buffer: &Self::CommandBufferId) {
gfx_select!(*command_buffer => self.command_buffer_destroy(*command_buffer))
}
fn render_bundle_drop(&self, render_bundle: &Self::RenderBundleId) {
gfx_select!(*render_bundle => self.render_bundle_destroy(*render_bundle))
}
fn compute_pipeline_drop(&self, pipeline: &Self::ComputePipelineId) {
gfx_select!(*pipeline => self.compute_pipeline_destroy(*pipeline))
}
@@ -670,7 +779,7 @@ impl crate::Context for Context {
gfx_select!(*pipeline => self.render_pipeline_destroy(*pipeline))
}
fn encoder_copy_buffer_to_buffer(
fn command_encoder_copy_buffer_to_buffer(
&self,
encoder: &Self::CommandEncoderId,
source: &Self::BufferId,
@@ -689,7 +798,7 @@ impl crate::Context for Context {
))
}
fn encoder_copy_buffer_to_texture(
fn command_encoder_copy_buffer_to_texture(
&self,
encoder: &Self::CommandEncoderId,
source: crate::BufferCopyView,
@@ -704,7 +813,7 @@ impl crate::Context for Context {
))
}
fn encoder_copy_texture_to_buffer(
fn command_encoder_copy_texture_to_buffer(
&self,
encoder: &Self::CommandEncoderId,
source: crate::TextureCopyView,
@@ -719,7 +828,7 @@ impl crate::Context for Context {
))
}
fn encoder_copy_texture_to_texture(
fn command_encoder_copy_texture_to_texture(
&self,
encoder: &Self::CommandEncoderId,
source: crate::TextureCopyView,
@@ -734,11 +843,14 @@ impl crate::Context for Context {
))
}
fn encoder_begin_compute_pass(&self, encoder: &Self::CommandEncoderId) -> Self::ComputePassId {
fn command_encoder_begin_compute_pass(
&self,
encoder: &Self::CommandEncoderId,
) -> Self::ComputePassId {
unsafe { wgc::command::RawPass::new_compute(*encoder) }
}
fn encoder_end_compute_pass(
fn command_encoder_end_compute_pass(
&self,
encoder: &Self::CommandEncoderId,
pass: &mut Self::ComputePassId,
@@ -752,7 +864,7 @@ impl crate::Context for Context {
unsafe { pass.invalidate() };
}
fn encoder_begin_render_pass<'a>(
fn command_encoder_begin_render_pass<'a>(
&self,
encoder: &Self::CommandEncoderId,
desc: &crate::RenderPassDescriptor<'a, '_>,
@@ -795,7 +907,7 @@ impl crate::Context for Context {
}
}
fn encoder_end_render_pass(
fn command_encoder_end_render_pass(
&self,
encoder: &Self::CommandEncoderId,
pass: &mut Self::RenderPassId,
@@ -809,11 +921,20 @@ impl crate::Context for Context {
unsafe { pass.invalidate() };
}
fn encoder_finish(&self, encoder: &Self::CommandEncoderId) -> Self::CommandBufferId {
fn command_encoder_finish(&self, encoder: &Self::CommandEncoderId) -> Self::CommandBufferId {
let desc = wgt::CommandBufferDescriptor::default();
gfx_select!(*encoder => self.command_encoder_finish(*encoder, &desc))
}
fn render_bundle_encoder_finish(
&self,
encoder: Self::RenderBundleEncoderId,
desc: &crate::RenderBundleDescriptor,
) -> Self::RenderBundleId {
let owned_label = OwnedLabel::new(desc.label.as_deref());
gfx_select!(encoder.parent() => self.render_bundle_encoder_finish(encoder, &desc.map_label(|_| owned_label.as_ptr()), PhantomData))
}
fn queue_write_buffer(
&self,
queue: &Self::QueueId,

View File

@@ -84,7 +84,7 @@ impl crate::ComputePassInner<Context> for ComputePass {
}
}
impl crate::RenderPassInner<Context> for RenderPass {
impl crate::RenderInner<Context> for RenderPass {
fn set_pipeline(&mut self, pipeline: &Sendable<web_sys::GpuRenderPipeline>) {
self.0.set_pipeline(&pipeline.0);
}
@@ -124,28 +124,6 @@ impl crate::RenderPassInner<Context> for RenderPass {
self.0
.set_vertex_buffer_with_f64_and_f64(slot, &buffer.0, offset as f64, size.0 as f64);
}
fn set_blend_color(&mut self, color: wgt::Color) {
self.0
.set_blend_color_with_gpu_color_dict(&map_color(color));
}
fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32) {
self.0.set_scissor_rect(x, y, width, height);
}
fn set_viewport(
&mut self,
x: f32,
y: f32,
width: f32,
height: f32,
min_depth: f32,
max_depth: f32,
) {
self.0
.set_viewport(x, y, width, height, min_depth, max_depth);
}
fn set_stencil_reference(&mut self, reference: u32) {
self.0.set_stencil_reference(reference);
}
fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
self.0
.draw_with_instance_count_and_first_vertex_and_first_instance(
@@ -183,6 +161,34 @@ impl crate::RenderPassInner<Context> for RenderPass {
}
}
impl crate::RenderPassInner<Context> for RenderPass {
fn set_blend_color(&mut self, color: wgt::Color) {
self.0
.set_blend_color_with_gpu_color_dict(&map_color(color));
}
fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32) {
self.0.set_scissor_rect(x, y, width, height);
}
fn set_viewport(
&mut self,
x: f32,
y: f32,
width: f32,
height: f32,
min_depth: f32,
max_depth: f32,
) {
self.0
.set_viewport(x, y, width, height, min_depth, max_depth);
}
fn set_stencil_reference(&mut self, reference: u32) {
self.0.set_stencil_reference(reference);
}
fn execute_bundles<'a, I: Iterator<Item = &'a ()>>(&mut self, render_bundles: I) {
unimplemented!()
}
}
fn map_texture_format(texture_format: wgt::TextureFormat) -> web_sys::GpuTextureFormat {
use web_sys::GpuTextureFormat as tf;
use wgt::TextureFormat;
@@ -615,10 +621,12 @@ impl crate::Context for Context {
type ComputePipelineId = Sendable<web_sys::GpuComputePipeline>;
type CommandEncoderId = web_sys::GpuCommandEncoder;
type ComputePassId = ComputePass;
type RenderPassId = RenderPass;
type CommandBufferId = Sendable<web_sys::GpuCommandBuffer>;
type RenderBundleEncoderId = RenderPass; //web_sys::GpuRenderBundleEncoder;
type RenderBundleId = (); //web_sys::GpuRenderBundle;
type SurfaceId = Sendable<web_sys::GpuCanvasContext>;
type SwapChainId = Sendable<web_sys::GpuSwapChain>;
type RenderPassId = RenderPass;
type SwapChainOutputDetail = SwapChainOutputDetail;
@@ -1027,6 +1035,14 @@ impl crate::Context for Context {
.create_command_encoder_with_descriptor(&mapped_desc)
}
fn device_create_render_bundle_encoder(
&self,
_device: &Self::DeviceId,
_desc: &wgt::RenderBundleEncoderDescriptor,
) -> Self::RenderBundleEncoderId {
unimplemented!()
}
fn device_drop(&self, _device: &Self::DeviceId) {
// Device is dropped automatically
}
@@ -1117,40 +1133,43 @@ impl crate::Context for Context {
}
fn texture_drop(&self, _texture: &Self::TextureId) {
// Buffer is dropped automatically
// Dropped automatically
}
fn texture_view_drop(&self, _texture_view: &Self::TextureViewId) {
// Buffer is dropped automatically
// Dropped automatically
}
fn sampler_drop(&self, _sampler: &Self::SamplerId) {
// Buffer is dropped automatically
// Dropped automatically
}
fn buffer_drop(&self, _buffer: &Self::BufferId) {
// Buffer is dropped automatically
// Dropped automatically
}
fn bind_group_drop(&self, _bind_group: &Self::BindGroupId) {
// Buffer is dropped automatically
// Dropped automatically
}
fn bind_group_layout_drop(&self, _bind_group_layout: &Self::BindGroupLayoutId) {
// Buffer is dropped automatically
// Dropped automatically
}
fn pipeline_layout_drop(&self, _pipeline_layout: &Self::PipelineLayoutId) {
// Buffer is dropped automatically
// Dropped automatically
}
fn shader_module_drop(&self, _shader_module: &Self::ShaderModuleId) {
// Buffer is dropped automatically
// Dropped automatically
}
fn command_buffer_drop(&self, _command_buffer: &Self::CommandBufferId) {
// Buffer is dropped automatically
// Dropped automatically
}
fn render_bundle_drop(&self, _render_bundle: &Self::RenderBundleId) {
// Dropped automatically
}
fn compute_pipeline_drop(&self, _pipeline: &Self::ComputePipelineId) {
// Buffer is dropped automatically
// Dropped automatically
}
fn render_pipeline_drop(&self, _pipeline: &Self::RenderPipelineId) {
// Buffer is dropped automatically
// Dropped automatically
}
fn encoder_copy_buffer_to_buffer(
fn command_encoder_copy_buffer_to_buffer(
&self,
encoder: &Self::CommandEncoderId,
source: &Self::BufferId,
@@ -1168,7 +1187,7 @@ impl crate::Context for Context {
)
}
fn encoder_copy_buffer_to_texture(
fn command_encoder_copy_buffer_to_texture(
&self,
encoder: &Self::CommandEncoderId,
source: crate::BufferCopyView,
@@ -1182,7 +1201,7 @@ impl crate::Context for Context {
)
}
fn encoder_copy_texture_to_buffer(
fn command_encoder_copy_texture_to_buffer(
&self,
encoder: &Self::CommandEncoderId,
source: crate::TextureCopyView,
@@ -1196,7 +1215,7 @@ impl crate::Context for Context {
)
}
fn encoder_copy_texture_to_texture(
fn command_encoder_copy_texture_to_texture(
&self,
encoder: &Self::CommandEncoderId,
source: crate::TextureCopyView,
@@ -1210,7 +1229,10 @@ impl crate::Context for Context {
)
}
fn encoder_begin_compute_pass(&self, encoder: &Self::CommandEncoderId) -> Self::ComputePassId {
fn command_encoder_begin_compute_pass(
&self,
encoder: &Self::CommandEncoderId,
) -> Self::ComputePassId {
let mut mapped_desc = web_sys::GpuComputePassDescriptor::new();
if let Some(ref label) = encoder.label() {
mapped_desc.label(label);
@@ -1218,7 +1240,7 @@ impl crate::Context for Context {
ComputePass(encoder.begin_compute_pass_with_descriptor(&mapped_desc))
}
fn encoder_end_compute_pass(
fn command_encoder_end_compute_pass(
&self,
_encoder: &Self::CommandEncoderId,
pass: &mut Self::ComputePassId,
@@ -1226,7 +1248,7 @@ impl crate::Context for Context {
pass.0.end_pass();
}
fn encoder_begin_render_pass<'a>(
fn command_encoder_begin_render_pass<'a>(
&self,
encoder: &Self::CommandEncoderId,
desc: &crate::RenderPassDescriptor<'a, '_>,
@@ -1284,7 +1306,7 @@ impl crate::Context for Context {
RenderPass(encoder.begin_render_pass(&mapped_desc))
}
fn encoder_end_render_pass(
fn command_encoder_end_render_pass(
&self,
_encoder: &Self::CommandEncoderId,
pass: &mut Self::RenderPassId,
@@ -1292,7 +1314,7 @@ impl crate::Context for Context {
pass.0.end_pass();
}
fn encoder_finish(&self, encoder: &Self::CommandEncoderId) -> Self::CommandBufferId {
fn command_encoder_finish(&self, encoder: &Self::CommandEncoderId) -> Self::CommandBufferId {
let mut mapped_desc = web_sys::GpuCommandBufferDescriptor::new();
if let Some(ref label) = encoder.label() {
mapped_desc.label(label);
@@ -1300,6 +1322,14 @@ impl crate::Context for Context {
Sendable(encoder.finish_with_descriptor(&mapped_desc))
}
fn render_bundle_encoder_finish(
&self,
_encoder: Self::RenderBundleEncoderId,
_desc: &crate::RenderBundleDescriptor,
) -> Self::RenderBundleId {
unimplemented!()
}
fn queue_write_buffer(
&self,
_queue: &Self::QueueId,

View File

@@ -24,11 +24,11 @@ pub use wgt::{
BufferUsage, Color, ColorStateDescriptor, ColorWrite, CommandBufferDescriptor, CompareFunction,
CullMode, DepthStencilStateDescriptor, DeviceDescriptor, DynamicOffset, Extensions, Extent3d,
FilterMode, FrontFace, IndexFormat, InputStepMode, Limits, LoadOp, Origin3d, PowerPreference,
PresentMode, PrimitiveTopology, RasterizationStateDescriptor, ShaderLocation, ShaderStage,
StencilOperation, StencilStateFaceDescriptor, StoreOp, SwapChainDescriptor, SwapChainStatus,
TextureAspect, TextureComponentType, TextureDataLayout, TextureDimension, TextureFormat,
TextureUsage, TextureViewDimension, UnsafeExtensions, VertexAttributeDescriptor, VertexFormat,
BIND_BUFFER_ALIGNMENT, COPY_BYTES_PER_ROW_ALIGNMENT,
PresentMode, PrimitiveTopology, RasterizationStateDescriptor, RenderBundleEncoderDescriptor,
ShaderLocation, ShaderStage, StencilOperation, StencilStateFaceDescriptor, StoreOp,
SwapChainDescriptor, SwapChainStatus, TextureAspect, TextureComponentType, TextureDataLayout,
TextureDimension, TextureFormat, TextureUsage, TextureViewDimension, UnsafeExtensions,
VertexAttributeDescriptor, VertexFormat, BIND_BUFFER_ALIGNMENT, COPY_BYTES_PER_ROW_ALIGNMENT,
};
use backend::Context as C;
@@ -49,7 +49,7 @@ trait ComputePassInner<Ctx: Context> {
);
}
trait RenderPassInner<Ctx: Context> {
trait RenderInner<Ctx: Context> {
fn set_pipeline(&mut self, pipeline: &Ctx::RenderPipelineId);
fn set_bind_group(
&mut self,
@@ -65,7 +65,18 @@ trait RenderPassInner<Ctx: Context> {
offset: BufferAddress,
size: BufferSize,
);
fn set_blend_color(&mut self, color: wgt::Color);
fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>);
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
fn draw_indirect(&mut self, indirect_buffer: &Ctx::BufferId, indirect_offset: BufferAddress);
fn draw_indexed_indirect(
&mut self,
indirect_buffer: &Ctx::BufferId,
indirect_offset: BufferAddress,
);
}
trait RenderPassInner<Ctx: Context>: RenderInner<Ctx> {
fn set_blend_color(&mut self, color: Color);
fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32);
fn set_viewport(
&mut self,
@@ -77,36 +88,34 @@ trait RenderPassInner<Ctx: Context> {
max_depth: f32,
);
fn set_stencil_reference(&mut self, reference: u32);
fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>);
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
fn draw_indirect(&mut self, indirect_buffer: &Ctx::BufferId, indirect_offset: BufferAddress);
fn draw_indexed_indirect(
fn execute_bundles<'a, I: Iterator<Item = &'a Ctx::RenderBundleId>>(
&mut self,
indirect_buffer: &Ctx::BufferId,
indirect_offset: BufferAddress,
render_bundles: I,
);
}
trait Context: Sized {
type AdapterId: Send + Sync;
type DeviceId: Send + Sync;
type QueueId: Send + Sync;
type ShaderModuleId: Send + Sync;
type BindGroupLayoutId: Send + Sync;
type BindGroupId: Send + Sync;
type TextureViewId: Send + Sync;
type SamplerId: Send + Sync;
type BufferId: Send + Sync;
type TextureId: Send + Sync;
type PipelineLayoutId: Send + Sync;
type RenderPipelineId: Send + Sync;
type ComputePipelineId: Send + Sync;
type AdapterId: Send + Sync + 'static;
type DeviceId: Send + Sync + 'static;
type QueueId: Send + Sync + 'static;
type ShaderModuleId: Send + Sync + 'static;
type BindGroupLayoutId: Send + Sync + 'static;
type BindGroupId: Send + Sync + 'static;
type TextureViewId: Send + Sync + 'static;
type SamplerId: Send + Sync + 'static;
type BufferId: Send + Sync + 'static;
type TextureId: Send + Sync + 'static;
type PipelineLayoutId: Send + Sync + 'static;
type RenderPipelineId: Send + Sync + 'static;
type ComputePipelineId: Send + Sync + 'static;
type CommandEncoderId;
type ComputePassId: ComputePassInner<Self>;
type CommandBufferId: Send + Sync;
type SurfaceId: Send + Sync;
type SwapChainId: Send + Sync;
type RenderPassId: RenderPassInner<Self>;
type CommandBufferId: Send + Sync;
type RenderBundleEncoderId: RenderInner<Self>;
type RenderBundleId: Send + Sync + 'static;
type SurfaceId: Send + Sync + 'static;
type SwapChainId: Send + Sync + 'static;
type SwapChainOutputDetail: Send;
@@ -123,8 +132,8 @@ trait Context: Sized {
fn instance_request_adapter(
&self,
options: &RequestAdapterOptions<'_>,
unsafe_extensions: wgt::UnsafeExtensions,
backends: wgt::BackendBit,
unsafe_extensions: UnsafeExtensions,
backends: BackendBit,
) -> Self::RequestAdapterFuture;
fn adapter_request_device(
&self,
@@ -193,6 +202,11 @@ trait Context: Sized {
device: &Self::DeviceId,
desc: &CommandEncoderDescriptor,
) -> Self::CommandEncoderId;
fn device_create_render_bundle_encoder(
&self,
device: &Self::DeviceId,
desc: &RenderBundleEncoderDescriptor,
) -> Self::RenderBundleEncoderId;
fn device_drop(&self, device: &Self::DeviceId);
fn device_poll(&self, device: &Self::DeviceId, maintain: Maintain);
@@ -238,10 +252,11 @@ trait Context: Sized {
fn pipeline_layout_drop(&self, pipeline_layout: &Self::PipelineLayoutId);
fn shader_module_drop(&self, shader_module: &Self::ShaderModuleId);
fn command_buffer_drop(&self, command_buffer: &Self::CommandBufferId);
fn render_bundle_drop(&self, render_bundle: &Self::RenderBundleId);
fn compute_pipeline_drop(&self, pipeline: &Self::ComputePipelineId);
fn render_pipeline_drop(&self, pipeline: &Self::RenderPipelineId);
fn encoder_copy_buffer_to_buffer(
fn command_encoder_copy_buffer_to_buffer(
&self,
encoder: &Self::CommandEncoderId,
source: &Self::BufferId,
@@ -250,21 +265,21 @@ trait Context: Sized {
destination_offset: BufferAddress,
copy_size: BufferAddress,
);
fn encoder_copy_buffer_to_texture(
fn command_encoder_copy_buffer_to_texture(
&self,
encoder: &Self::CommandEncoderId,
source: BufferCopyView,
destination: TextureCopyView,
copy_size: Extent3d,
);
fn encoder_copy_texture_to_buffer(
fn command_encoder_copy_texture_to_buffer(
&self,
encoder: &Self::CommandEncoderId,
source: TextureCopyView,
destination: BufferCopyView,
copy_size: Extent3d,
);
fn encoder_copy_texture_to_texture(
fn command_encoder_copy_texture_to_texture(
&self,
encoder: &Self::CommandEncoderId,
source: TextureCopyView,
@@ -272,23 +287,31 @@ trait Context: Sized {
copy_size: Extent3d,
);
fn encoder_begin_compute_pass(&self, encoder: &Self::CommandEncoderId) -> Self::ComputePassId;
fn encoder_end_compute_pass(
fn command_encoder_begin_compute_pass(
&self,
encoder: &Self::CommandEncoderId,
) -> Self::ComputePassId;
fn command_encoder_end_compute_pass(
&self,
encoder: &Self::CommandEncoderId,
pass: &mut Self::ComputePassId,
);
fn encoder_begin_render_pass<'a>(
fn command_encoder_begin_render_pass<'a>(
&self,
encoder: &Self::CommandEncoderId,
desc: &RenderPassDescriptor<'a, '_>,
) -> Self::RenderPassId;
fn encoder_end_render_pass(
fn command_encoder_end_render_pass(
&self,
encoder: &Self::CommandEncoderId,
pass: &mut Self::RenderPassId,
);
fn encoder_finish(&self, encoder: &Self::CommandEncoderId) -> Self::CommandBufferId;
fn command_encoder_finish(&self, encoder: &Self::CommandEncoderId) -> Self::CommandBufferId;
fn render_bundle_encoder_finish(
&self,
encoder: Self::RenderBundleEncoderId,
desc: &RenderBundleDescriptor,
) -> Self::RenderBundleId;
fn queue_write_buffer(
&self,
queue: &Self::QueueId,
@@ -301,8 +324,8 @@ trait Context: Sized {
queue: &Self::QueueId,
texture: TextureCopyView,
data: &[u8],
data_layout: wgt::TextureDataLayout,
size: wgt::Extent3d,
data_layout: TextureDataLayout,
size: Extent3d,
);
fn queue_submit<I: Iterator<Item = Self::CommandBufferId>>(
&self,
@@ -462,7 +485,9 @@ pub struct Sampler {
impl Drop for Sampler {
fn drop(&mut self) {
self.context.sampler_drop(&self.id);
if !thread::panicking() {
self.context.sampler_drop(&self.id);
}
}
}
@@ -496,7 +521,9 @@ pub struct BindGroupLayout {
impl Drop for BindGroupLayout {
fn drop(&mut self) {
self.context.bind_group_layout_drop(&self.id);
if !thread::panicking() {
self.context.bind_group_layout_drop(&self.id);
}
}
}
@@ -513,7 +540,9 @@ pub struct BindGroup {
impl Drop for BindGroup {
fn drop(&mut self) {
self.context.bind_group_drop(&self.id);
if !thread::panicking() {
self.context.bind_group_drop(&self.id);
}
}
}
@@ -529,7 +558,9 @@ pub struct ShaderModule {
impl Drop for ShaderModule {
fn drop(&mut self) {
self.context.shader_module_drop(&self.id);
if !thread::panicking() {
self.context.shader_module_drop(&self.id);
}
}
}
@@ -543,7 +574,9 @@ pub struct PipelineLayout {
impl Drop for PipelineLayout {
fn drop(&mut self) {
self.context.pipeline_layout_drop(&self.id);
if !thread::panicking() {
self.context.pipeline_layout_drop(&self.id);
}
}
}
@@ -558,7 +591,9 @@ pub struct RenderPipeline {
impl Drop for RenderPipeline {
fn drop(&mut self) {
self.context.render_pipeline_drop(&self.id);
if !thread::panicking() {
self.context.render_pipeline_drop(&self.id);
}
}
}
@@ -570,7 +605,9 @@ pub struct ComputePipeline {
impl Drop for ComputePipeline {
fn drop(&mut self) {
self.context.compute_pipeline_drop(&self.id);
if !thread::panicking() {
self.context.compute_pipeline_drop(&self.id);
}
}
}
@@ -586,8 +623,10 @@ pub struct CommandBuffer {
impl Drop for CommandBuffer {
fn drop(&mut self) {
if let Some(ref id) = self.id {
self.context.command_buffer_drop(id);
if !thread::panicking() {
if let Some(ref id) = self.id {
self.context.command_buffer_drop(id);
}
}
}
}
@@ -619,6 +658,32 @@ pub struct ComputePass<'a> {
parent: &'a mut CommandEncoder,
}
/// An object that encodes GPU operations into a render bundle.
///
/// It only supports a handful of render commands, but it makes them re-usable.
pub struct RenderBundleEncoder<'a> {
context: Arc<C>,
id: <C as Context>::RenderBundleEncoderId,
_parent: &'a Device,
/// This type should be !Send !Sync, because it represents an allocation on this thread's
/// command buffer.
_p: PhantomData<*const u8>,
}
/// A finished render bundle.
pub struct RenderBundle {
context: Arc<C>,
id: <C as Context>::RenderBundleId,
}
impl Drop for RenderBundle {
fn drop(&mut self) {
if !thread::panicking() {
self.context.render_bundle_drop(&self.id);
}
}
}
/// A handle to a command queue on a device.
///
/// A `Queue` executes recorded [`CommandBuffer`] objects.
@@ -766,12 +831,10 @@ pub struct RenderPassDescriptor<'a, 'b> {
pub type BufferDescriptor<'a> = wgt::BufferDescriptor<Option<&'a str>>;
/// A description of a command encoder.
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct CommandEncoderDescriptor<'a> {
/// An optional label to apply to the command encoder.
/// This can be useful for debugging and performance analysis.
pub label: Option<&'a str>,
}
pub type CommandEncoderDescriptor<'a> = wgt::CommandEncoderDescriptor<Option<&'a str>>;
/// A description of a render bundle.
pub type RenderBundleDescriptor<'a> = wgt::RenderBundleDescriptor<Option<&'a str>>;
/// A description of a texture.
pub type TextureDescriptor<'a> = wgt::TextureDescriptor<Option<&'a str>>;
@@ -810,7 +873,7 @@ pub struct BufferCopyView<'a> {
pub buffer: &'a Buffer,
/// The layout of the texture data in this buffer.
pub layout: wgt::TextureDataLayout,
pub layout: TextureDataLayout,
}
/// A view of a texture which can be used to copy to or from a buffer or another texture.
@@ -838,8 +901,8 @@ impl Instance {
#[cfg(not(target_arch = "wasm32"))]
pub fn enumerate_adapters(
&self,
unsafe_extensions: wgt::UnsafeExtensions,
backends: wgt::BackendBit,
unsafe_extensions: UnsafeExtensions,
backends: BackendBit,
) -> impl Iterator<Item = Adapter> {
let context = Arc::clone(&self.context);
self.context
@@ -900,7 +963,7 @@ impl Instance {
pub fn request_adapter(
&self,
options: &RequestAdapterOptions<'_>,
unsafe_extensions: wgt::UnsafeExtensions,
unsafe_extensions: UnsafeExtensions,
backends: BackendBit,
) -> impl Future<Output = Option<Adapter>> + Send {
let context = Arc::clone(&self.context);
@@ -985,6 +1048,19 @@ impl Device {
}
}
/// Creates an empty [`RenderBundleEncoder`].
pub fn create_render_bundle_encoder(
&self,
desc: &RenderBundleEncoderDescriptor,
) -> RenderBundleEncoder {
RenderBundleEncoder {
context: Arc::clone(&self.context),
id: Context::device_create_render_bundle_encoder(&*self.context, &self.id, desc),
_parent: self,
_p: Default::default(),
}
}
/// Creates a new bind group.
pub fn create_bind_group(&self, desc: &BindGroupDescriptor) -> BindGroup {
BindGroup {
@@ -1087,7 +1163,9 @@ impl Device {
impl Drop for Device {
fn drop(&mut self) {
self.context.device_drop(&self.id);
if !thread::panicking() {
self.context.device_drop(&self.id);
}
}
}
@@ -1283,7 +1361,9 @@ impl BufferSlice<'_> {
impl Drop for Buffer {
fn drop(&mut self) {
self.context.buffer_drop(&self.id);
if !thread::panicking() {
self.context.buffer_drop(&self.id);
}
}
}
@@ -1309,7 +1389,7 @@ impl Texture {
impl Drop for Texture {
fn drop(&mut self) {
if self.owned {
if self.owned && !thread::panicking() {
self.context.texture_drop(&self.id);
}
}
@@ -1317,7 +1397,7 @@ impl Drop for Texture {
impl Drop for TextureView {
fn drop(&mut self) {
if self.owned {
if self.owned && !thread::panicking() {
self.context.texture_view_drop(&self.id);
}
}
@@ -1328,7 +1408,7 @@ impl CommandEncoder {
pub fn finish(self) -> CommandBuffer {
CommandBuffer {
context: Arc::clone(&self.context),
id: Some(Context::encoder_finish(&*self.context, &self.id)),
id: Some(Context::command_encoder_finish(&*self.context, &self.id)),
}
}
@@ -1340,7 +1420,7 @@ impl CommandEncoder {
desc: &RenderPassDescriptor<'a, '_>,
) -> RenderPass<'a> {
RenderPass {
id: Context::encoder_begin_render_pass(&*self.context, &self.id, desc),
id: Context::command_encoder_begin_render_pass(&*self.context, &self.id, desc),
parent: self,
}
}
@@ -1350,7 +1430,7 @@ impl CommandEncoder {
/// This function returns a [`ComputePass`] object which records a single compute pass.
pub fn begin_compute_pass(&mut self) -> ComputePass {
ComputePass {
id: Context::encoder_begin_compute_pass(&*self.context, &self.id),
id: Context::command_encoder_begin_compute_pass(&*self.context, &self.id),
parent: self,
}
}
@@ -1364,7 +1444,7 @@ impl CommandEncoder {
destination_offset: BufferAddress,
copy_size: BufferAddress,
) {
Context::encoder_copy_buffer_to_buffer(
Context::command_encoder_copy_buffer_to_buffer(
&*self.context,
&self.id,
&source.id,
@@ -1382,7 +1462,7 @@ impl CommandEncoder {
destination: TextureCopyView,
copy_size: Extent3d,
) {
Context::encoder_copy_buffer_to_texture(
Context::command_encoder_copy_buffer_to_texture(
&*self.context,
&self.id,
source,
@@ -1398,7 +1478,7 @@ impl CommandEncoder {
destination: BufferCopyView,
copy_size: Extent3d,
) {
Context::encoder_copy_texture_to_buffer(
Context::command_encoder_copy_texture_to_buffer(
&*self.context,
&self.id,
source,
@@ -1414,7 +1494,7 @@ impl CommandEncoder {
destination: TextureCopyView,
copy_size: Extent3d,
) {
Context::encoder_copy_texture_to_texture(
Context::command_encoder_copy_texture_to_texture(
&*self.context,
&self.id,
source,
@@ -1432,14 +1512,14 @@ impl<'a> RenderPass<'a> {
bind_group: &'a BindGroup,
offsets: &[DynamicOffset],
) {
RenderPassInner::set_bind_group(&mut self.id, index, &bind_group.id, offsets)
RenderInner::set_bind_group(&mut self.id, index, &bind_group.id, offsets)
}
/// Sets the active render pipeline.
///
/// Subsequent draw calls will exhibit the behavior defined by `pipeline`.
pub fn set_pipeline(&mut self, pipeline: &'a RenderPipeline) {
RenderPassInner::set_pipeline(&mut self.id, &pipeline.id)
RenderInner::set_pipeline(&mut self.id, &pipeline.id)
}
pub fn set_blend_color(&mut self, color: Color) {
@@ -1451,7 +1531,7 @@ impl<'a> RenderPass<'a> {
/// Subsequent calls to [`draw_indexed`](RenderPass::draw_indexed) on this [`RenderPass`] will
/// use `buffer` as the source index buffer.
pub fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'a>) {
RenderPassInner::set_index_buffer(
RenderInner::set_index_buffer(
&mut self.id,
&buffer_slice.buffer.id,
buffer_slice.offset,
@@ -1472,7 +1552,7 @@ impl<'a> RenderPass<'a> {
/// [`RenderPass`]: struct.RenderPass.html
/// [`RenderPipelineDescriptor::vertex_buffers`]: struct.RenderPipelineDescriptor.html#structfield.vertex_buffers
pub fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'a>) {
RenderPassInner::set_vertex_buffer(
RenderInner::set_vertex_buffer(
&mut self.id,
slot,
&buffer_slice.buffer.id,
@@ -1506,7 +1586,7 @@ impl<'a> RenderPass<'a> {
///
/// The active vertex buffers can be set with [`RenderPass::set_vertex_buffer`].
pub fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
RenderPassInner::draw(&mut self.id, vertices, instances)
RenderInner::draw(&mut self.id, vertices, instances)
}
/// Draws indexed primitives using the active index buffer and the active vertex buffers.
@@ -1514,7 +1594,7 @@ impl<'a> RenderPass<'a> {
/// The active index buffer can be set with [`RenderPass::set_index_buffer`], while the active
/// vertex buffers can be set with [`RenderPass::set_vertex_buffer`].
pub fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
RenderPassInner::draw_indexed(&mut self.id, indices, base_vertex, instances);
RenderInner::draw_indexed(&mut self.id, indices, base_vertex, instances);
}
/// Draws primitives from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
@@ -1562,6 +1642,11 @@ impl<'a> RenderPass<'a> {
self.id
.draw_indexed_indirect(&indirect_buffer.id, indirect_offset);
}
pub fn execute_bundles<I: Iterator<Item = &'a RenderBundle>>(&mut self, render_bundles: I) {
self.id
.execute_bundles(render_bundles.into_iter().map(|rb| &rb.id))
}
}
impl<'a> Drop for RenderPass<'a> {
@@ -1569,7 +1654,7 @@ impl<'a> Drop for RenderPass<'a> {
if !thread::panicking() {
self.parent
.context
.encoder_end_render_pass(&self.parent.id, &mut self.id);
.command_encoder_end_render_pass(&self.parent.id, &mut self.id);
}
}
}
@@ -1612,11 +1697,134 @@ impl<'a> Drop for ComputePass<'a> {
if !thread::panicking() {
self.parent
.context
.encoder_end_compute_pass(&self.parent.id, &mut self.id);
.command_encoder_end_compute_pass(&self.parent.id, &mut self.id);
}
}
}
impl<'a> RenderBundleEncoder<'a> {
/// Finishes recording and returns a [`RenderBundle`] that can be executed in other render passes.
pub fn finish(self, desc: &RenderBundleDescriptor) -> RenderBundle {
RenderBundle {
context: Arc::clone(&self.context),
id: Context::render_bundle_encoder_finish(&*self.context, self.id, desc),
}
}
/// Sets the active bind group for a given bind group index.
pub fn set_bind_group(
&mut self,
index: u32,
bind_group: &'a BindGroup,
offsets: &[DynamicOffset],
) {
RenderInner::set_bind_group(&mut self.id, index, &bind_group.id, offsets)
}
/// Sets the active render pipeline.
///
/// Subsequent draw calls will exhibit the behavior defined by `pipeline`.
pub fn set_pipeline(&mut self, pipeline: &'a RenderPipeline) {
RenderInner::set_pipeline(&mut self.id, &pipeline.id)
}
/// Sets the active index buffer.
///
/// Subsequent calls to [`draw_indexed`](RenderBundleEncoder::draw_indexed) on this [`RenderBundleEncoder`] will
/// use `buffer` as the source index buffer.
pub fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'a>) {
RenderInner::set_index_buffer(
&mut self.id,
&buffer_slice.buffer.id,
buffer_slice.offset,
buffer_slice.size,
)
}
/// Assign a vertex buffer to a slot.
///
/// Subsequent calls to [`draw`] and [`draw_indexed`] on this
/// [`RenderBundleEncoder`] will use `buffer` as one of the source vertex buffers.
///
/// The `slot` refers to the index of the matching descriptor in
/// [`RenderPipelineDescriptor::vertex_buffers`].
///
/// [`draw`]: #method.draw
/// [`draw_indexed`]: #method.draw_indexed
/// [`RenderBundleEncoder`]: struct.RenderBundleEncoder.html
/// [`RenderPipelineDescriptor::vertex_buffers`]: struct.RenderPipelineDescriptor.html#structfield.vertex_buffers
pub fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'a>) {
RenderInner::set_vertex_buffer(
&mut self.id,
slot,
&buffer_slice.buffer.id,
buffer_slice.offset,
buffer_slice.size,
)
}
/// Draws primitives from the active vertex buffer(s).
///
/// The active vertex buffers can be set with [`RenderBundleEncoder::set_vertex_buffer`].
pub fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
RenderInner::draw(&mut self.id, vertices, instances)
}
/// Draws indexed primitives using the active index buffer and the active vertex buffers.
///
/// The active index buffer can be set with [`RenderBundleEncoder::set_index_buffer`], while the active
/// vertex buffers can be set with [`RenderBundleEncoder::set_vertex_buffer`].
pub fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
RenderInner::draw_indexed(&mut self.id, indices, base_vertex, instances);
}
/// Draws primitives from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
///
/// The active vertex buffers can be set with [`RenderBundleEncoder::set_vertex_buffer`].
///
/// The structure expected in `indirect_buffer` is the following:
///
/// ```rust
/// #[repr(C)]
/// struct DrawIndirect {
/// vertex_count: u32, // The number of vertices to draw.
/// instance_count: u32, // The number of instances to draw.
/// base_vertex: u32, // The Index of the first vertex to draw.
/// base_instance: u32, // The instance ID of the first instance to draw.
/// }
/// ```
pub fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress) {
self.id.draw_indirect(&indirect_buffer.id, indirect_offset);
}
/// Draws indexed primitives using the active index buffer and the active vertex buffers,
/// based on the contents of the `indirect_buffer`.
///
/// The active index buffer can be set with [`RenderBundleEncoder::set_index_buffer`], while the active
/// vertex buffers can be set with [`RenderBundleEncoder::set_vertex_buffer`].
///
/// The structure expected in `indirect_buffer` is the following:
///
/// ```rust
/// #[repr(C)]
/// struct DrawIndexedIndirect {
/// vertex_count: u32, // The number of vertices to draw.
/// instance_count: u32, // The number of instances to draw.
/// base_index: u32, // The base index within the index buffer.
/// vertex_offset: i32, // The value added to the vertex index before indexing into the vertex buffer.
/// base_instance: u32, // The instance ID of the first instance to draw.
/// }
/// ```
pub fn draw_indexed_indirect(
&mut self,
indirect_buffer: &'a Buffer,
indirect_offset: BufferAddress,
) {
self.id
.draw_indexed_indirect(&indirect_buffer.id, indirect_offset);
}
}
impl Queue {
/// Schedule a data write into `buffer` starting at `offset`.
pub fn write_buffer(&self, buffer: &Buffer, offset: BufferAddress, data: &[u8]) {
@@ -1628,8 +1836,8 @@ impl Queue {
&self,
texture: TextureCopyView,
data: &[u8],
data_layout: wgt::TextureDataLayout,
size: wgt::Extent3d,
data_layout: TextureDataLayout,
size: Extent3d,
) {
Context::queue_write_texture(&*self.context, &self.id, texture, data, data_layout, size)
}