hal/gles: encoding copies and draws

This commit is contained in:
Dzmitry Malyshau
2021-06-22 00:34:06 -04:00
committed by Dzmitry Malyshau
parent 31da0f2278
commit 4d42bef7f8
3 changed files with 253 additions and 28 deletions

View File

@@ -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<super::Api> 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<super::CommandBuffer, crate::DeviceError> {
Ok(mem::take(&mut self.cmd_buffer))
}
unsafe fn reset_all<I>(&mut self, command_buffers: I) {}
unsafe fn reset_all<I>(&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<Item = crate::BufferBarrier<'a, super::Api>>,
{
}
unsafe fn transition_textures<'a, T>(&mut self, barriers: T)
unsafe fn transition_textures<'a, T>(&mut self, _barriers: T)
where
T: Iterator<Item = crate::TextureBarrier<'a, super::Api>>,
{
}
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<T>(
@@ -31,16 +48,40 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
src: &super::Buffer,
dst: &super::Buffer,
regions: T,
) {
) where
T: Iterator<Item = crate::BufferCopy>,
{
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<T>(
&mut self,
src: &super::Texture,
src_usage: crate::TextureUse,
_src_usage: crate::TextureUse,
dst: &super::Texture,
regions: T,
) {
) where
T: Iterator<Item = crate::TextureCopy>,
{
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<T>(
@@ -48,16 +89,40 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
src: &super::Buffer,
dst: &super::Texture,
regions: T,
) {
) where
T: Iterator<Item = crate::BufferTextureCopy>,
{
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<T>(
&mut self,
src: &super::Texture,
src_usage: crate::TextureUse,
_src_usage: crate::TextureUse,
dst: &super::Buffer,
regions: T,
) {
) where
T: Iterator<Item = crate::BufferTextureCopy>,
{
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<super::Api> 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<super::Api> 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<super::Api> 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<super::Api> 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<super::Api> 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::<wgt::DrawIndirectArgs>() 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<super::Api> 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::<wgt::DrawIndexedIndirectArgs>() 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<super::Api> 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,
});
}
}

View File

@@ -254,6 +254,7 @@ impl crate::Device<super::Api> for super::Device {
) -> Result<super::CommandEncoder, crate::DeviceError> {
Ok(super::CommandEncoder {
cmd_buffer: super::CommandBuffer::default(),
state: super::CommandState::default(),
})
}
unsafe fn destroy_command_encoder(&self, _encoder: super::CommandEncoder) {}

View File

@@ -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<u32>),
PushDebugGroup(Range<u32>),
PopDebugGroup,
}
#[derive(Default)]
pub struct CommandBuffer {
label: Option<String>,
commands: Vec<Command>,
data: Vec<u8>,
}
impl CommandBuffer {
fn add_marker(&mut self, marker: &str) -> Range<u32> {
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<Api> for Queue {