[rs] Expose more functions on the web backend

This commit is contained in:
Joshua Groves
2020-04-14 00:03:36 -02:30
committed by Josh Groves
parent 1f4b8801f5
commit 0fbb75ea95
3 changed files with 330 additions and 162 deletions

View File

@@ -351,6 +351,10 @@ pub(crate) fn buffer_unmap(buffer: &BufferId) {
wgn::wgpu_buffer_unmap(*buffer);
}
pub(crate) fn buffer_drop(buffer: &BufferId) {
wgn::wgpu_buffer_destroy(*buffer);
}
pub(crate) fn device_create_buffer(device: &DeviceId, desc: &BufferDescriptor) -> crate::Buffer {
let owned_label = OwnedLabel::new(desc.label.as_deref());
crate::Buffer {
@@ -445,6 +449,20 @@ pub(crate) fn command_encoder_copy_texture_to_buffer(
);
}
pub(crate) fn command_encoder_copy_texture_to_texture(
command_encoder: &CommandEncoderId,
source: crate::TextureCopyView,
destination: crate::TextureCopyView,
copy_size: wgt::Extent3d,
) {
wgn::wgpu_command_encoder_copy_texture_to_texture(
*command_encoder,
&map_texture_copy_view(source),
&map_texture_copy_view(destination),
copy_size,
);
}
pub(crate) fn begin_compute_pass(command_encoder: &CommandEncoderId) -> ComputePassId {
unsafe { wgn::wgpu_command_encoder_begin_compute_pass(*command_encoder, None) }
}
@@ -554,10 +572,50 @@ pub(crate) fn buffer_map_read(
future
}
pub(crate) fn buffer_map_write(
buffer: &crate::Buffer,
start: wgt::BufferAddress,
size: wgt::BufferAddress,
) -> impl Future<Output = Result<crate::BufferWriteMapping, crate::BufferAsyncErr>> {
let (future, completion) = native_gpu_future::new_gpu_future(buffer.id, size);
extern "C" fn buffer_map_write_future_wrapper(
status: wgc::resource::BufferMapAsyncStatus,
data: *mut u8,
user_data: *mut u8,
) {
let completion =
unsafe { native_gpu_future::GpuFutureCompletion::from_raw(user_data as _) };
let (buffer_id, size) = completion.get_buffer_info();
if let wgc::resource::BufferMapAsyncStatus::Success = status {
completion.complete(Ok(crate::BufferWriteMapping {
detail: BufferWriteMappingDetail {
data,
size: size as usize,
buffer_id,
},
}));
} else {
completion.complete(Err(crate::BufferAsyncErr));
}
}
wgn::wgpu_buffer_map_write_async(
buffer.id,
start,
size,
buffer_map_write_future_wrapper,
completion.to_raw() as _,
);
future
}
pub(crate) struct BufferReadMappingDetail {
pub(crate) buffer_id: BufferId,
data: *const u8,
size: usize,
pub(crate) buffer_id: BufferId,
}
impl BufferReadMappingDetail {
@@ -566,6 +624,18 @@ impl BufferReadMappingDetail {
}
}
pub(crate) struct BufferWriteMappingDetail {
pub(crate) buffer_id: BufferId,
data: *mut u8,
size: usize,
}
impl BufferWriteMappingDetail {
pub(crate) fn as_slice(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.data as *mut u8, self.size) }
}
}
pub(crate) fn device_create_surface<W: raw_window_handle::HasRawWindowHandle>(
window: &W,
) -> SurfaceId {
@@ -633,6 +703,12 @@ pub(crate) fn render_pass_set_pipeline(
}
}
pub(crate) fn render_pass_set_blend_color(render_pass: &RenderPassEncoderId, color: wgt::Color) {
unsafe {
wgn::wgpu_render_pass_set_blend_color(render_pass.as_mut().unwrap(), &color);
}
}
pub(crate) fn render_pass_set_bind_group(
render_pass: &RenderPassEncoderId,
index: u32,
@@ -684,6 +760,46 @@ pub(crate) fn render_pass_set_vertex_buffer<'a>(
};
}
pub(crate) fn render_pass_set_scissor_rect(
render_pass: &RenderPassEncoderId,
x: u32,
y: u32,
width: u32,
height: u32,
) {
unsafe {
wgn::wgpu_render_pass_set_scissor_rect(render_pass.as_mut().unwrap(), x, y, width, height);
}
}
pub(crate) fn render_pass_set_viewport(
render_pass: &RenderPassEncoderId,
x: f32,
y: f32,
width: f32,
height: f32,
min_depth: f32,
max_depth: f32,
) {
unsafe {
wgn::wgpu_render_pass_set_viewport(
render_pass.as_mut().unwrap(),
x,
y,
width,
height,
min_depth,
max_depth,
);
}
}
pub(crate) fn render_pass_set_stencil_reference(render_pass: &RenderPassEncoderId, reference: u32) {
unsafe {
wgn::wgpu_render_pass_set_stencil_reference(render_pass.as_mut().unwrap(), reference);
}
}
pub(crate) fn render_pass_draw(
render_pass: &RenderPassEncoderId,
vertices: Range<u32>,
@@ -718,6 +834,34 @@ pub(crate) fn render_pass_draw_indexed(
}
}
pub(crate) fn render_pass_draw_indirect<'a>(
render_pass: &RenderPassEncoderId,
indirect_buffer: &'a crate::Buffer,
indirect_offset: wgt::BufferAddress,
) {
unsafe {
wgn::wgpu_render_pass_draw_indirect(
render_pass.as_mut().unwrap(),
indirect_buffer.id,
indirect_offset,
);
}
}
pub(crate) fn render_pass_draw_indexed_indirect<'a>(
render_pass: &RenderPassEncoderId,
indirect_buffer: &'a crate::Buffer,
indirect_offset: wgt::BufferAddress,
) {
unsafe {
wgn::wgpu_render_pass_draw_indexed_indirect(
render_pass.as_mut().unwrap(),
indirect_buffer.id,
indirect_offset,
);
}
}
pub(crate) fn render_pass_end_pass(render_pass: &RenderPassEncoderId) {
unsafe {
wgn::wgpu_render_pass_end_pass(*render_pass);
@@ -731,6 +875,14 @@ pub(crate) fn texture_create_view(
wgn::wgpu_texture_create_view(*texture, desc)
}
pub(crate) fn texture_drop(texture: &TextureId) {
wgn::wgpu_texture_destroy(*texture);
}
pub(crate) fn texture_view_drop(texture_view: &TextureViewId) {
wgn::wgpu_texture_view_destroy(*texture_view);
}
pub(crate) fn swap_chain_present(swap_chain: &SwapChainId) {
wgn::wgpu_swap_chain_present(*swap_chain);
}

View File

@@ -533,6 +533,10 @@ fn map_address_mode(mode: wgt::AddressMode) -> web_sys::GpuAddressMode {
}
}
fn map_color(color: wgt::Color) -> web_sys::GpuColorDict {
web_sys::GpuColorDict::new(color.a, color.b, color.g, color.r)
}
pub(crate) fn create_render_pipeline(
device: &DeviceId,
desc: &RenderPipelineDescriptor,
@@ -665,6 +669,10 @@ pub(crate) fn buffer_unmap(buffer: &BufferId) {
buffer.unmap();
}
pub(crate) fn buffer_drop(_buffer: &BufferId) {
// Buffer is dropped automatically
}
pub(crate) fn device_create_buffer(device: &DeviceId, desc: &BufferDescriptor) -> crate::Buffer {
let mapped_desc = web_sys::GpuBufferDescriptor::new(desc.size as f64, desc.usage.bits());
crate::Buffer {
@@ -752,6 +760,19 @@ pub(crate) fn command_encoder_copy_texture_to_buffer(
);
}
pub(crate) fn command_encoder_copy_texture_to_texture(
command_encoder: &CommandEncoderId,
source: crate::TextureCopyView,
destination: crate::TextureCopyView,
copy_size: wgt::Extent3d,
) {
command_encoder.copy_texture_to_texture_with_gpu_extent_3d_dict(
&map_texture_copy_view(source),
&map_texture_copy_view(destination),
&map_extent_3d(copy_size),
);
}
pub(crate) fn begin_compute_pass(command_encoder: &CommandEncoderId) -> ComputePassId {
let mapped_desc = web_sys::GpuComputePassDescriptor::new();
command_encoder.begin_compute_pass_with_descriptor(&mapped_desc)
@@ -831,6 +852,26 @@ pub(crate) async fn buffer_map_read(
})
}
pub(crate) async fn buffer_map_write(
buffer: &crate::Buffer,
_start: wgt::BufferAddress,
_size: wgt::BufferAddress,
) -> Result<crate::BufferWriteMapping, crate::BufferAsyncErr> {
let array_buffer_promise = buffer.id.map_write_async();
let array_buffer: js_sys::ArrayBuffer =
wasm_bindgen_futures::JsFuture::from(array_buffer_promise)
.await
.expect("Unable to map buffer")
.into();
let view = js_sys::Uint8Array::new(&array_buffer);
Ok(crate::BufferWriteMapping {
detail: BufferWriteMappingDetail {
buffer_id: buffer.id.clone(),
mapped: view.to_vec(),
},
})
}
pub(crate) struct BufferReadMappingDetail {
pub(crate) buffer_id: BufferId,
mapped: Vec<u8>,
@@ -842,6 +883,17 @@ impl BufferReadMappingDetail {
}
}
pub(crate) struct BufferWriteMappingDetail {
pub(crate) buffer_id: BufferId,
mapped: Vec<u8>,
}
impl BufferWriteMappingDetail {
pub(crate) fn as_slice(&mut self) -> &mut [u8] {
&mut self.mapped[..]
}
}
pub(crate) fn device_create_surface<W: raw_window_handle::HasRawWindowHandle>(
window: &W,
) -> SurfaceId {
@@ -901,12 +953,7 @@ pub(crate) fn command_encoder_begin_render_pass<'a>(
let mut mapped_color_attachment = web_sys::GpuRenderPassColorAttachmentDescriptor::new(
&ca.attachment.id,
&match ca.load_op {
wgt::LoadOp::Clear => {
let color = ca.clear_color;
let mapped_color =
web_sys::GpuColorDict::new(color.a, color.b, color.g, color.r);
wasm_bindgen::JsValue::from(mapped_color)
}
wgt::LoadOp::Clear => wasm_bindgen::JsValue::from(map_color(ca.clear_color)),
wgt::LoadOp::Load => wasm_bindgen::JsValue::from(web_sys::GpuLoadOp::Load),
},
);
@@ -952,6 +999,10 @@ pub(crate) fn render_pass_set_pipeline(
render_pass.set_pipeline(&pipeline);
}
pub(crate) fn render_pass_set_blend_color(render_pass: &RenderPassEncoderId, color: wgt::Color) {
render_pass.set_blend_color_with_gpu_color_dict(&map_color(color));
}
pub(crate) fn render_pass_set_bind_group(
render_pass: &RenderPassEncoderId,
index: u32,
@@ -997,6 +1048,32 @@ pub(crate) fn render_pass_set_vertex_buffer<'a>(
);
}
pub(crate) fn render_pass_set_scissor_rect(
render_pass: &RenderPassEncoderId,
x: u32,
y: u32,
width: u32,
height: u32,
) {
render_pass.set_scissor_rect(x, y, width, height);
}
pub(crate) fn render_pass_set_viewport(
render_pass: &RenderPassEncoderId,
x: f32,
y: f32,
width: f32,
height: f32,
min_depth: f32,
max_depth: f32,
) {
render_pass.set_viewport(x, y, width, height, min_depth, max_depth);
}
pub(crate) fn render_pass_set_stencil_reference(render_pass: &RenderPassEncoderId, reference: u32) {
render_pass.set_stencil_reference(reference);
}
pub(crate) fn render_pass_draw(
render_pass: &RenderPassEncoderId,
vertices: Range<u32>,
@@ -1026,6 +1103,22 @@ pub(crate) fn render_pass_draw_indexed(
);
}
pub(crate) fn render_pass_draw_indirect<'a>(
render_pass: &RenderPassEncoderId,
indirect_buffer: &'a crate::Buffer,
indirect_offset: wgt::BufferAddress,
) {
render_pass.draw_indirect_with_f64(&indirect_buffer.id, indirect_offset as f64);
}
pub(crate) fn render_pass_draw_indexed_indirect<'a>(
render_pass: &RenderPassEncoderId,
indirect_buffer: &'a crate::Buffer,
indirect_offset: wgt::BufferAddress,
) {
render_pass.draw_indexed_indirect_with_f64(&indirect_buffer.id, indirect_offset as f64);
}
pub(crate) fn render_pass_end_pass(render_pass: &RenderPassEncoderId) {
render_pass.end_pass();
}
@@ -1050,6 +1143,14 @@ pub(crate) fn texture_create_view(
}
}
pub(crate) fn texture_drop(_texture: &TextureId) {
// Texture is dropped automatically
}
pub(crate) fn texture_view_drop(_texture_view: &TextureViewId) {
// Texture view is dropped automatically
}
pub(crate) fn swap_chain_present(_swap_chain: &SwapChainId) {
// Swapchain is presented automatically
}

View File

@@ -528,26 +528,23 @@ impl Surface {
}
}
/*
#[cfg(any(target_os = "ios", target_os = "macos"))]
pub fn create_surface_from_core_animation_layer(layer: *mut std::ffi::c_void) -> Self {
Surface {
id: wgn::wgpu_create_surface_from_metal_layer(layer),
}
#[cfg(any(target_os = "ios", target_os = "macos"))]
pub fn create_surface_from_core_animation_layer(layer: *mut std::ffi::c_void) -> Self {
Surface {
id: wgn::wgpu_create_surface_from_metal_layer(layer),
}
*/
}
}
impl Adapter {
/*
/// Retrieves all available [`Adapter`]s that match the given backends.
pub fn enumerate(backends: BackendBit) -> Vec<Self> {
wgn::wgpu_enumerate_adapters(backends)
.into_iter()
.map(|id| Adapter { id })
.collect()
}
*/
/// Retrieves all available [`Adapter`]s that match the given backends.
#[cfg(not(target_arch = "wasm32"))]
pub fn enumerate(backends: BackendBit) -> Vec<Self> {
wgn::wgpu_enumerate_adapters(backends)
.into_iter()
.map(|id| Adapter { id })
.collect()
}
/// Retrieves an [`Adapter`] which matches the given options.
///
@@ -723,11 +720,8 @@ impl Drop for BufferReadMapping {
}
}
/*
pub struct BufferWriteMapping {
data: *mut u8,
size: usize,
buffer_id: wgc::id::BufferId,
detail: backend::BufferWriteMappingDetail,
}
unsafe impl Send for BufferWriteMapping {}
@@ -735,16 +729,15 @@ unsafe impl Sync for BufferWriteMapping {}
impl BufferWriteMapping {
pub fn as_slice(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.data as *mut u8, self.size) }
self.detail.as_slice()
}
}
impl Drop for BufferWriteMapping {
fn drop(&mut self) {
wgn::wgpu_buffer_unmap(self.buffer_id);
backend::buffer_unmap(&self.detail.buffer_id);
}
}
*/
impl Buffer {
/// Map the buffer for reading. The result is returned in a future.
@@ -763,63 +756,29 @@ impl Buffer {
backend::buffer_map_read(self, start, size)
}
/*
/// Map the buffer for writing. The result is returned in a future.
///
/// See the documentation of (map_read)[#method.map_read] for more information about
/// how to run this future.
pub fn map_write(
&self,
start: BufferAddress,
size: BufferAddress,
) -> impl Future<Output = Result<BufferWriteMapping, BufferAsyncErr>> {
let (future, completion) = native_gpu_future::new_gpu_future(self.id, size);
/// Map the buffer for writing. The result is returned in a future.
///
/// See the documentation of (map_read)[#method.map_read] for more information about
/// how to run this future.
pub fn map_write(
&self,
start: BufferAddress,
size: BufferAddress,
) -> impl Future<Output = Result<BufferWriteMapping, BufferAsyncErr>> + '_ {
backend::buffer_map_write(self, start, size)
}
extern "C" fn buffer_map_write_future_wrapper(
status: wgc::resource::BufferMapAsyncStatus,
data: *mut u8,
user_data: *mut u8,
) {
let completion =
unsafe { native_gpu_future::GpuFutureCompletion::from_raw(user_data as _) };
let (buffer_id, size) = completion.get_buffer_info();
if let wgc::resource::BufferMapAsyncStatus::Success = status {
completion.complete(Ok(BufferWriteMapping {
data,
size: size as usize,
buffer_id,
}));
} else {
completion.complete(Err(BufferAsyncErr));
}
}
wgn::wgpu_buffer_map_write_async(
self.id,
start,
size,
buffer_map_write_future_wrapper,
completion.to_raw() as _,
);
future
}
/// Flushes any pending write operations and unmaps the buffer from host memory.
pub fn unmap(&self) {
wgn::wgpu_buffer_unmap(self.id);
}
*/
}
/*
impl Drop for Buffer {
fn drop(&mut self) {
wgn::wgpu_buffer_destroy(self.id);
/// Flushes any pending write operations and unmaps the buffer from host memory.
pub fn unmap(&self) {
backend::buffer_unmap(&self.id);
}
}
impl Drop for Buffer {
fn drop(&mut self) {
backend::buffer_drop(&self.id);
}
}
*/
impl Texture {
/// Creates a view of this texture.
@@ -839,11 +798,10 @@ impl Texture {
}
}
/*
impl Drop for Texture {
fn drop(&mut self) {
if self.owned {
wgn::wgpu_texture_destroy(self.id);
backend::texture_drop(&self.id);
}
}
}
@@ -851,11 +809,10 @@ impl Drop for Texture {
impl Drop for TextureView {
fn drop(&mut self) {
if self.owned {
wgn::wgpu_texture_view_destroy(self.id);
backend::texture_view_drop(&self.id);
}
}
}
*/
impl CommandEncoder {
/// Finishes recording and returns a [`CommandBuffer`] that can be submitted for execution.
@@ -927,22 +884,15 @@ impl CommandEncoder {
backend::command_encoder_copy_texture_to_buffer(&self.id, source, destination, copy_size);
}
/*
/// Copy data from one texture to another.
pub fn copy_texture_to_texture(
&mut self,
source: TextureCopyView,
destination: TextureCopyView,
copy_size: Extent3d,
) {
wgn::wgpu_command_encoder_copy_texture_to_texture(
self.id,
&source.into_native(),
&destination.into_native(),
copy_size,
);
}
*/
/// Copy data from one texture to another.
pub fn copy_texture_to_texture(
&mut self,
source: TextureCopyView,
destination: TextureCopyView,
copy_size: Extent3d,
) {
backend::command_encoder_copy_texture_to_texture(&self.id, source, destination, copy_size);
}
}
impl<'a> RenderPass<'a> {
@@ -963,14 +913,9 @@ impl<'a> RenderPass<'a> {
backend::render_pass_set_pipeline(&self.id, &pipeline.id)
}
/*
pub fn set_blend_color(&mut self, color: Color) {
unsafe {
wgn::wgpu_render_pass_set_blend_color(self.id.as_mut().unwrap(), &color);
}
}
}
*/
pub fn set_blend_color(&mut self, color: Color) {
backend::render_pass_set_blend_color(&self.id, color)
}
/// Sets the active index buffer.
///
@@ -1011,42 +956,26 @@ impl<'a> RenderPass<'a> {
backend::render_pass_set_vertex_buffer(&self.id, slot, buffer, offset, size)
}
/*
/// Sets the scissor region.
///
/// Subsequent draw calls will discard any fragments that fall outside this region.
pub fn set_scissor_rect(&mut self, x: u32, y: u32, w: u32, h: u32) {
unsafe {
wgn::wgpu_render_pass_set_scissor_rect(self.id.as_mut().unwrap(), x, y, w, h);
}
}
/// Sets the scissor region.
///
/// Subsequent draw calls will discard any fragments that fall outside this region.
pub fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32) {
backend::render_pass_set_scissor_rect(&self.id, x, y, width, height);
}
/// Sets the viewport region.
///
/// Subsequent draw calls will draw any fragments in this region.
pub fn set_viewport(&mut self, x: f32, y: f32, w: f32, h: f32, min_depth: f32, max_depth: f32) {
unsafe {
wgn::wgpu_render_pass_set_viewport(
self.id.as_mut().unwrap(),
x,
y,
w,
h,
min_depth,
max_depth,
);
}
}
/// Sets the viewport region.
///
/// Subsequent draw calls will draw any fragments in this region.
pub fn set_viewport(&mut self, x: f32, y: f32, w: f32, h: f32, min_depth: f32, max_depth: f32) {
backend::render_pass_set_viewport(&self.id, x, y, w, h, min_depth, max_depth);
}
/// Sets the stencil reference.
///
/// Subsequent stencil tests will test against this value.
pub fn set_stencil_reference(&mut self, reference: u32) {
unsafe {
wgn::wgpu_render_pass_set_stencil_reference(self.id.as_mut().unwrap(), reference);
}
}
*/
/// Sets the stencil reference.
///
/// Subsequent stencil tests will test against this value.
pub fn set_stencil_reference(&mut self, reference: u32) {
backend::render_pass_set_stencil_reference(&self.id, reference);
}
/// Draws primitives from the active vertex buffer(s).
///
@@ -1063,7 +992,6 @@ impl<'a> RenderPass<'a> {
backend::render_pass_draw_indexed(&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 [`RenderPass::set_vertex_buffer`].
@@ -1080,13 +1008,7 @@ impl<'a> RenderPass<'a> {
/// }
/// ```
pub fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress) {
unsafe {
wgn::wgpu_render_pass_draw_indirect(
self.id.as_mut().unwrap(),
indirect_buffer.id,
indirect_offset,
);
}
backend::render_pass_draw_indirect(&self.id, indirect_buffer, indirect_offset);
}
/// Draws indexed primitives using the active index buffer and the active vertex buffers,
@@ -1112,15 +1034,8 @@ impl<'a> RenderPass<'a> {
indirect_buffer: &'a Buffer,
indirect_offset: BufferAddress,
) {
unsafe {
wgn::wgpu_render_pass_draw_indexed_indirect(
self.id.as_mut().unwrap(),
indirect_buffer.id,
indirect_offset,
);
}
backend::render_pass_draw_indexed_indirect(&self.id, indirect_buffer, indirect_offset);
}
*/
}
impl<'a> Drop for RenderPass<'a> {