From 4d42bef7f81f2ded1bc6f5c774af50d958bf8ef6 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Tue, 22 Jun 2021 00:34:06 -0400 Subject: [PATCH] hal/gles: encoding copies and draws --- wgpu-hal/src/gles/command.rs | 181 ++++++++++++++++++++++++++++++----- wgpu-hal/src/gles/device.rs | 1 + wgpu-hal/src/gles/mod.rs | 99 ++++++++++++++++++- 3 files changed, 253 insertions(+), 28 deletions(-) diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index d7b506ae6b..989e44770f 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -1,29 +1,46 @@ +use super::Command as C; use super::Resource; //TEMP use std::{mem, ops::Range}; +impl super::CommandBuffer { + fn clear(&mut self) { + self.label = None; + self.commands.clear(); + self.data.clear(); + } +} + impl crate::CommandEncoder for super::CommandEncoder { unsafe fn begin_encoding(&mut self, label: crate::Label) -> Result<(), crate::DeviceError> { + self.cmd_buffer.label = label.map(str::to_string); Ok(()) } - unsafe fn discard_encoding(&mut self) {} + unsafe fn discard_encoding(&mut self) { + self.cmd_buffer.clear(); + } unsafe fn end_encoding(&mut self) -> Result { Ok(mem::take(&mut self.cmd_buffer)) } - unsafe fn reset_all(&mut self, command_buffers: I) {} + unsafe fn reset_all(&mut self, _command_buffers: I) {} - unsafe fn transition_buffers<'a, T>(&mut self, barriers: T) + unsafe fn transition_buffers<'a, T>(&mut self, _barriers: T) where T: Iterator>, { } - unsafe fn transition_textures<'a, T>(&mut self, barriers: T) + unsafe fn transition_textures<'a, T>(&mut self, _barriers: T) where T: Iterator>, { } unsafe fn fill_buffer(&mut self, buffer: &super::Buffer, range: crate::MemoryRange, value: u8) { + self.cmd_buffer.commands.push(C::FillBuffer { + dst: buffer.raw, + range, + value, + }); } unsafe fn copy_buffer_to_buffer( @@ -31,16 +48,40 @@ impl crate::CommandEncoder for super::CommandEncoder { src: &super::Buffer, dst: &super::Buffer, regions: T, - ) { + ) where + T: Iterator, + { + for copy in regions { + self.cmd_buffer.commands.push(C::CopyBufferToBuffer { + src: src.raw, + src_target: src.target, + dst: dst.raw, + dst_target: dst.target, + copy, + }) + } } unsafe fn copy_texture_to_texture( &mut self, src: &super::Texture, - src_usage: crate::TextureUse, + _src_usage: crate::TextureUse, dst: &super::Texture, regions: T, - ) { + ) where + T: Iterator, + { + let (src_raw, src_target) = src.as_native(); + let (dst_raw, dst_target) = dst.as_native(); + for copy in regions { + self.cmd_buffer.commands.push(C::CopyTextureToTexture { + src: src_raw, + src_target: src_target, + dst: dst_raw, + dst_target: dst_target, + copy, + }) + } } unsafe fn copy_buffer_to_texture( @@ -48,16 +89,40 @@ impl crate::CommandEncoder for super::CommandEncoder { src: &super::Buffer, dst: &super::Texture, regions: T, - ) { + ) where + T: Iterator, + { + let (dst_raw, dst_target) = dst.as_native(); + for copy in regions { + self.cmd_buffer.commands.push(C::CopyBufferToTexture { + src: src.raw, + src_target: src.target, + dst: dst_raw, + dst_target: dst_target, + copy, + }) + } } unsafe fn copy_texture_to_buffer( &mut self, src: &super::Texture, - src_usage: crate::TextureUse, + _src_usage: crate::TextureUse, dst: &super::Buffer, regions: T, - ) { + ) where + T: Iterator, + { + let (src_raw, src_target) = src.as_native(); + for copy in regions { + self.cmd_buffer.commands.push(C::CopyTextureToBuffer { + src: src_raw, + src_target: src_target, + dst: dst.raw, + dst_target: dst.target, + copy, + }) + } } unsafe fn begin_query(&mut self, set: &Resource, index: u32) {} @@ -95,9 +160,17 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { } - unsafe fn insert_debug_marker(&mut self, label: &str) {} - unsafe fn begin_debug_marker(&mut self, group_label: &str) {} - unsafe fn end_debug_marker(&mut self) {} + unsafe fn insert_debug_marker(&mut self, label: &str) { + let range = self.cmd_buffer.add_marker(label); + self.cmd_buffer.commands.push(C::InsertDebugMarker(range)); + } + unsafe fn begin_debug_marker(&mut self, group_label: &str) { + let range = self.cmd_buffer.add_marker(group_label); + self.cmd_buffer.commands.push(C::PushDebugGroup(range)); + } + unsafe fn end_debug_marker(&mut self) { + self.cmd_buffer.commands.push(C::PopDebugGroup); + } unsafe fn set_render_pipeline(&mut self, pipeline: &Resource) {} @@ -106,6 +179,11 @@ impl crate::CommandEncoder for super::CommandEncoder { binding: crate::BufferBinding<'a, super::Api>, format: wgt::IndexFormat, ) { + self.state.index_offset = binding.offset; + self.state.index_format = format; + self.cmd_buffer + .commands + .push(C::SetIndexBuffer(binding.buffer.raw)); } unsafe fn set_vertex_buffer<'a>( &mut self, @@ -125,6 +203,13 @@ impl crate::CommandEncoder for super::CommandEncoder { start_instance: u32, instance_count: u32, ) { + debug_assert_eq!(start_instance, 0); + self.cmd_buffer.commands.push(C::Draw { + primitive: self.state.primitive, + start_vertex, + vertex_count, + instance_count, + }); } unsafe fn draw_indexed( &mut self, @@ -134,6 +219,20 @@ impl crate::CommandEncoder for super::CommandEncoder { start_instance: u32, instance_count: u32, ) { + debug_assert_eq!(start_instance, 0); + let (index_size, index_type) = match self.state.index_format { + wgt::IndexFormat::Uint16 => (2, glow::UNSIGNED_SHORT), + wgt::IndexFormat::Uint32 => (4, glow::UNSIGNED_INT), + }; + let index_offset = self.state.index_offset + index_size * start_index as wgt::BufferAddress; + self.cmd_buffer.commands.push(C::DrawIndexed { + primitive: self.state.primitive, + index_type, + index_offset, + index_count, + base_vertex, + instance_count, + }); } unsafe fn draw_indirect( &mut self, @@ -141,6 +240,15 @@ impl crate::CommandEncoder for super::CommandEncoder { offset: wgt::BufferAddress, draw_count: u32, ) { + for draw in 0..draw_count as wgt::BufferAddress { + let indirect_offset = + offset + draw * mem::size_of::() as wgt::BufferAddress; + self.cmd_buffer.commands.push(C::DrawIndirect { + primitive: self.state.primitive, + indirect_buf: buffer.raw, + indirect_offset, + }); + } } unsafe fn draw_indexed_indirect( &mut self, @@ -148,24 +256,40 @@ impl crate::CommandEncoder for super::CommandEncoder { offset: wgt::BufferAddress, draw_count: u32, ) { + let index_type = match self.state.index_format { + wgt::IndexFormat::Uint16 => glow::UNSIGNED_SHORT, + wgt::IndexFormat::Uint32 => glow::UNSIGNED_INT, + }; + for draw in 0..draw_count as wgt::BufferAddress { + let indirect_offset = offset + + draw * mem::size_of::() as wgt::BufferAddress; + self.cmd_buffer.commands.push(C::DrawIndexedIndirect { + primitive: self.state.primitive, + index_type, + indirect_buf: buffer.raw, + indirect_offset, + }); + } } unsafe fn draw_indirect_count( &mut self, - buffer: &super::Buffer, - offset: wgt::BufferAddress, - count_buffer: &super::Buffer, - count_offset: wgt::BufferAddress, - max_count: u32, + _buffer: &super::Buffer, + _offset: wgt::BufferAddress, + _count_buffer: &super::Buffer, + _count_offset: wgt::BufferAddress, + _max_count: u32, ) { + unimplemented!() } unsafe fn draw_indexed_indirect_count( &mut self, - buffer: &super::Buffer, - offset: wgt::BufferAddress, - count_buffer: &super::Buffer, - count_offset: wgt::BufferAddress, - max_count: u32, + _buffer: &super::Buffer, + _offset: wgt::BufferAddress, + _count_buffer: &super::Buffer, + _count_offset: wgt::BufferAddress, + _max_count: u32, ) { + unimplemented!() } // compute @@ -175,6 +299,13 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn set_compute_pipeline(&mut self, pipeline: &Resource) {} - unsafe fn dispatch(&mut self, count: [u32; 3]) {} - unsafe fn dispatch_indirect(&mut self, buffer: &super::Buffer, offset: wgt::BufferAddress) {} + unsafe fn dispatch(&mut self, count: [u32; 3]) { + self.cmd_buffer.commands.push(C::Dispatch(count)); + } + unsafe fn dispatch_indirect(&mut self, buffer: &super::Buffer, offset: wgt::BufferAddress) { + self.cmd_buffer.commands.push(C::DispatchIndirect { + indirect_buf: buffer.raw, + indirect_offset: offset, + }); + } } diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 5e4d7fa8bd..4742ad54a6 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -254,6 +254,7 @@ impl crate::Device for super::Device { ) -> Result { Ok(super::CommandEncoder { cmd_buffer: super::CommandBuffer::default(), + state: super::CommandState::default(), }) } unsafe fn destroy_command_encoder(&self, _encoder: super::CommandEncoder) {} diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index d8d7a12b24..31ccbd18db 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -13,11 +13,10 @@ use self::egl::{Instance, Surface}; use glow::HasContext; -use std::sync::Arc; +use std::{ops::Range, sync::Arc}; #[derive(Clone)] pub struct Api; -pub struct Context; #[derive(Debug)] pub struct Resource; @@ -203,6 +202,15 @@ pub enum Texture { }, } +impl Texture { + fn as_native(&self) -> (glow::Texture, BindTarget) { + match *self { + Self::Renderbuffer { raw, .. } => panic!("Unexpected renderbuffer {}", raw), + Self::Texture { raw, target } => (raw, target), + } + } +} + #[derive(Debug)] pub enum TextureView { Renderbuffer { @@ -222,16 +230,101 @@ pub struct Sampler { } #[derive(Debug)] -enum Command {} +enum Command { + Draw { + primitive: u32, + start_vertex: u32, + vertex_count: u32, + instance_count: u32, + }, + DrawIndexed { + primitive: u32, + index_type: u32, + index_count: u32, + index_offset: wgt::BufferAddress, + base_vertex: i32, + instance_count: u32, + }, + DrawIndirect { + primitive: u32, + indirect_buf: glow::Buffer, + indirect_offset: wgt::BufferAddress, + }, + DrawIndexedIndirect { + primitive: u32, + index_type: u32, + indirect_buf: glow::Buffer, + indirect_offset: wgt::BufferAddress, + }, + Dispatch([u32; 3]), + DispatchIndirect { + indirect_buf: glow::Buffer, + indirect_offset: wgt::BufferAddress, + }, + FillBuffer { + dst: glow::Buffer, + range: crate::MemoryRange, + value: u8, + }, + CopyBufferToBuffer { + src: glow::Buffer, + src_target: BindTarget, + dst: glow::Buffer, + dst_target: BindTarget, + copy: crate::BufferCopy, + }, + CopyTextureToTexture { + src: glow::Texture, + src_target: BindTarget, + dst: glow::Texture, + dst_target: BindTarget, + copy: crate::TextureCopy, + }, + CopyBufferToTexture { + src: glow::Buffer, + src_target: BindTarget, + dst: glow::Texture, + dst_target: BindTarget, + copy: crate::BufferTextureCopy, + }, + CopyTextureToBuffer { + src: glow::Texture, + src_target: BindTarget, + dst: glow::Buffer, + dst_target: BindTarget, + copy: crate::BufferTextureCopy, + }, + SetIndexBuffer(glow::Buffer), + InsertDebugMarker(Range), + PushDebugGroup(Range), + PopDebugGroup, +} #[derive(Default)] pub struct CommandBuffer { + label: Option, commands: Vec, data: Vec, } +impl CommandBuffer { + fn add_marker(&mut self, marker: &str) -> Range { + let start = self.data.len() as u32; + self.data.extend(marker.as_bytes()); + start..self.data.len() as u32 + } +} + +#[derive(Default)] +struct CommandState { + primitive: u32, + index_format: wgt::IndexFormat, + index_offset: wgt::BufferAddress, +} + pub struct CommandEncoder { cmd_buffer: CommandBuffer, + state: CommandState, } impl crate::Queue for Queue {