Skip to content

Commit

Permalink
hal/gles: primitive state and framebuffer operations
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Jun 26, 2021
1 parent 6d8a20e commit af42298
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 50 deletions.
5 changes: 3 additions & 2 deletions wgpu-hal/src/gles/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl super::Adapter {
naga::back::glsl::Version::Embedded(value)
};

let mut features = wgt::Features::empty() | wgt::Features::NON_FILL_POLYGON_MODE;
let mut features = wgt::Features::empty();
features.set(
wgt::Features::DEPTH_CLAMPING,
extensions.contains("GL_EXT_depth_clamp"),
Expand Down Expand Up @@ -283,7 +283,7 @@ impl super::Adapter {
impl crate::Adapter<super::Api> for super::Adapter {
unsafe fn open(
&self,
_features: wgt::Features,
features: wgt::Features,
) -> Result<crate::OpenDevice<super::Api>, crate::DeviceError> {
let gl = &self.shared.context;
gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1);
Expand All @@ -300,6 +300,7 @@ impl crate::Adapter<super::Api> for super::Adapter {
},
queue: super::Queue {
shared: Arc::clone(&self.shared),
features,
draw_fbo: gl
.create_framebuffer()
.map_err(|_| crate::DeviceError::OutOfMemory)?,
Expand Down
65 changes: 60 additions & 5 deletions wgpu-hal/src/gles/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct TextureSlotDesc {
#[derive(Default)]
pub(super) struct State {
topology: u32,
primitive: super::PrimitiveState,
index_format: wgt::IndexFormat,
index_offset: wgt::BufferAddress,
vertex_buffers: [(super::VertexBufferDesc, super::BufferBinding); crate::MAX_VERTEX_BUFFERS],
Expand All @@ -27,6 +28,9 @@ pub(super) struct State {
depth_bias: wgt::DepthBiasState,
samplers: [Option<glow::Sampler>; super::MAX_SAMPLERS],
texture_slots: [TextureSlotDesc; super::MAX_TEXTURE_SLOTS],
render_size: wgt::Extent3d,
resolve_attachments: ArrayVec<[(u32, super::TextureView); crate::MAX_COLOR_TARGETS]>,
invalidate_attachments: ArrayVec<[u32; crate::MAX_COLOR_TARGETS + 2]>,
has_pass_label: bool,
dirty: Dirty,
}
Expand Down Expand Up @@ -223,12 +227,14 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
) where
T: Iterator<Item = crate::BufferCopy>,
{
//TODO: preserve `src.target` and `dst.target`
// at least for the buffers that require it.
for copy in regions {
self.cmd_buffer.commands.push(C::CopyBufferToBuffer {
src: src.raw,
src_target: src.target,
src_target: glow::COPY_READ_BUFFER,
dst: dst.raw,
dst_target: dst.target,
dst_target: glow::COPY_WRITE_BUFFER,
copy,
})
}
Expand Down Expand Up @@ -357,6 +363,9 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
// render

unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor<super::Api>) {
self.state.render_size = desc.extent;
self.state.resolve_attachments.clear();
self.state.invalidate_attachments.clear();
if let Some(label) = desc.label {
let range = self.cmd_buffer.add_marker(label);
self.cmd_buffer.commands.push(C::PushDebugGroup(range));
Expand All @@ -367,21 +376,44 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
self.cmd_buffer.commands.push(C::ResetFramebuffer);
for (i, cat) in desc.color_attachments.iter().enumerate() {
let attachment = glow::COLOR_ATTACHMENT0 + i as u32;
self.cmd_buffer.commands.push(C::SetFramebufferAttachment {
self.cmd_buffer.commands.push(C::BindAttachment {
attachment,
view: cat.target.view.clone(),
});
if let Some(ref rat) = cat.resolve_target {
self.state
.resolve_attachments
.push((attachment, rat.view.clone()));
}
if !cat.ops.contains(crate::AttachmentOp::STORE) {
self.state.invalidate_attachments.push(attachment);
}
}
if let Some(ref dsat) = desc.depth_stencil_attachment {
let attachment = match dsat.target.view.aspects {
let aspects = dsat.target.view.aspects;
let attachment = match aspects {
crate::FormatAspect::DEPTH => glow::DEPTH_ATTACHMENT,
crate::FormatAspect::STENCIL => glow::STENCIL_ATTACHMENT,
_ => glow::DEPTH_STENCIL_ATTACHMENT,
};
self.cmd_buffer.commands.push(C::SetFramebufferAttachment {
self.cmd_buffer.commands.push(C::BindAttachment {
attachment,
view: dsat.target.view.clone(),
});
if aspects.contains(crate::FormatAspect::DEPTH)
&& !dsat.depth_ops.contains(crate::AttachmentOp::STORE)
{
self.state
.invalidate_attachments
.push(glow::DEPTH_ATTACHMENT);
}
if aspects.contains(crate::FormatAspect::STENCIL)
&& !dsat.stencil_ops.contains(crate::AttachmentOp::STORE)
{
self.state
.invalidate_attachments
.push(glow::STENCIL_ATTACHMENT);
}
}

// set the draw buffers and states
Expand Down Expand Up @@ -437,13 +469,27 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
}
}
unsafe fn end_render_pass(&mut self) {
for (attachment, dst) in self.state.resolve_attachments.drain(..) {
self.cmd_buffer.commands.push(C::ResolveAttachment {
attachment,
dst,
size: self.state.render_size,
});
}
if !self.state.invalidate_attachments.is_empty() {
self.cmd_buffer.commands.push(C::InvalidateAttachments(
self.state.invalidate_attachments.clone(),
));
self.state.invalidate_attachments.clear();
}
if self.state.has_pass_label {
self.cmd_buffer.commands.push(C::PopDebugGroup);
self.state.has_pass_label = false;
}
self.state.dirty = Dirty::empty();
self.state.color_targets.clear();
self.state.vertex_attributes.clear();
self.state.primitive = super::PrimitiveState::default();
}

unsafe fn set_bind_group(
Expand Down Expand Up @@ -562,6 +608,15 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
state_desc.stride = pipe_desc.stride;
}

// set primitive state
let prim_state = conv::map_primitive_state(&pipeline.primitive);
if prim_state != self.state.primitive {
self.cmd_buffer
.commands
.push(C::SetPrimitive(prim_state.clone()));
self.state.primitive = prim_state;
}

// set depth/stencil states
let mut aspects = crate::FormatAspect::empty();
if pipeline.depth_bias != self.state.depth_bias {
Expand Down
16 changes: 16 additions & 0 deletions wgpu-hal/src/gles/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,22 @@ pub fn map_primitive_topology(topology: wgt::PrimitiveTopology) -> u32 {
}
}

pub(super) fn map_primitive_state(state: &wgt::PrimitiveState) -> super::PrimitiveState {
//Note: state.polygon_mode is not supported, see `Features::NON_FILL_POLYGON_MODE`
super::PrimitiveState {
front_face: match state.front_face {
wgt::FrontFace::Cw => glow::CW,
wgt::FrontFace::Ccw => glow::CCW,
},
cull_face: match state.cull_mode {
Some(wgt::Face::Front) => glow::FRONT,
Some(wgt::Face::Back) => glow::BACK,
None => 0,
},
clamp_depth: state.clamp_depth,
}
}

pub fn map_view_dimension(dim: wgt::TextureViewDimension) -> u32 {
use wgt::TextureViewDimension as Tvd;
match dim {
Expand Down
50 changes: 43 additions & 7 deletions wgpu-hal/src/gles/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,13 @@ impl super::Device {
}
super::BindingRegister::StorageBuffers => {
let index = gl.get_shader_storage_block_index(program, name).unwrap();
gl.shader_storage_block_binding(program, index, slot as _);
log::error!(
"Unable to re-map shader storage block {} to {}",
name,
index
);
//gl.shader_storage_block_binding(program, index, slot as _);
return Err(crate::DeviceError::Lost.into());
}
super::BindingRegister::Textures | super::BindingRegister::Images => {
let loc = gl.get_uniform_location(program, name).unwrap();
Expand Down Expand Up @@ -279,12 +285,18 @@ impl crate::Device<super::Api> for super::Device {
glow::ARRAY_BUFFER
};

let mut map_flags = glow::MAP_PERSISTENT_BIT;
let mut map_flags = 0;
if desc
.memory_flags
.contains(crate::MemoryFlag::PREFER_COHERENT)
.usage
.intersects(crate::BufferUse::MAP_READ | crate::BufferUse::MAP_WRITE)
{
map_flags |= glow::MAP_COHERENT_BIT;
map_flags |= glow::MAP_PERSISTENT_BIT;
if desc
.memory_flags
.contains(crate::MemoryFlag::PREFER_COHERENT)
{
map_flags |= glow::MAP_COHERENT_BIT;
}
}
if desc.usage.contains(crate::BufferUse::MAP_READ) {
map_flags |= glow::MAP_READ_BIT;
Expand Down Expand Up @@ -321,18 +333,24 @@ impl crate::Device<super::Api> for super::Device {
) -> Result<crate::BufferMapping, crate::DeviceError> {
let gl = &self.shared.context;

let is_coherent = buffer.map_flags & glow::MAP_COHERENT_BIT != 0;
let mut flags = buffer.map_flags | glow::MAP_UNSYNCHRONIZED_BIT;
if !is_coherent {
flags |= glow::MAP_FLUSH_EXPLICIT_BIT;
}

gl.bind_buffer(buffer.target, Some(buffer.raw));
let ptr = gl.map_buffer_range(
buffer.target,
range.start as i32,
(range.end - range.start) as i32,
buffer.map_flags,
flags,
);
gl.bind_buffer(buffer.target, None);

Ok(crate::BufferMapping {
ptr: NonNull::new(ptr).ok_or(crate::DeviceError::Lost)?,
is_coherent: buffer.map_flags & glow::MAP_COHERENT_BIT != 0,
is_coherent,
})
}
unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> Result<(), crate::DeviceError> {
Expand All @@ -347,6 +365,7 @@ impl crate::Device<super::Api> for super::Device {
I: Iterator<Item = crate::MemoryRange>,
{
let gl = &self.shared.context;
gl.bind_buffer(buffer.target, Some(buffer.raw));
for range in ranges {
gl.flush_mapped_buffer_range(
buffer.target,
Expand All @@ -360,6 +379,7 @@ impl crate::Device<super::Api> for super::Device {
I: Iterator<Item = crate::MemoryRange>,
{
let gl = &self.shared.context;
gl.bind_buffer(buffer.target, Some(buffer.raw));
for range in ranges {
gl.invalidate_buffer_sub_data(
buffer.target,
Expand Down Expand Up @@ -402,6 +422,8 @@ impl crate::Device<super::Api> for super::Device {
desc.size.height as i32,
);
}

gl.bind_renderbuffer(glow::RENDERBUFFER, None);
super::TextureInner::Renderbuffer { raw }
} else {
let raw = gl.create_texture().unwrap();
Expand Down Expand Up @@ -453,6 +475,20 @@ impl crate::Device<super::Api> for super::Device {
target
}
};

match desc.format.describe().sample_type {
wgt::TextureSampleType::Float { filterable: false }
| wgt::TextureSampleType::Uint
| wgt::TextureSampleType::Sint => {
// reset default filtering mode
gl.tex_parameter_i32(target, glow::TEXTURE_MIN_FILTER, glow::NEAREST as i32);
gl.tex_parameter_i32(target, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32);
}
wgt::TextureSampleType::Float { filterable: true }
| wgt::TextureSampleType::Depth => {}
}

gl.bind_texture(target, None);
super::TextureInner::Texture { raw, target }
};

Expand Down
5 changes: 3 additions & 2 deletions wgpu-hal/src/gles/egl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ fn gl_debug_message_callback(source: u32, gltype: u32, id: u32, severity: u32, m
message
);

if log_severity == log::Level::Error && false {
if cfg!(debug_assertions) && log_severity == log::Level::Error {
std::process::exit(1);
}
}
Expand Down Expand Up @@ -558,7 +558,7 @@ impl crate::Instance<super::Api> for Instance {

if ret != 0 {
log::error!("Error returned from ANativeWindow_setBuffersGeometry");
return Err(w::InitError::UnsupportedWindowHandle);
return Err(crate::InstanceError);
}
}

Expand Down Expand Up @@ -665,6 +665,7 @@ impl Surface {
crate::SurfaceError::Lost
})?;

gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None);
gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(sc.framebuffer));
gl.blit_framebuffer(
0,
Expand Down
19 changes: 18 additions & 1 deletion wgpu-hal/src/gles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ pub struct Device {

pub struct Queue {
shared: Arc<AdapterShared>,
features: wgt::Features,
draw_fbo: glow::Framebuffer,
copy_fbo: glow::Framebuffer,
temp_query_results: Vec<u64>,
Expand Down Expand Up @@ -397,6 +398,15 @@ struct StencilState {
back: StencilSide,
}

#[derive(Clone, Debug, Default, PartialEq)]
struct PrimitiveState {
front_face: u32,
cull_face: u32,
clamp_depth: bool,
}

type InvalidatedAttachments = arrayvec::ArrayVec<[u32; crate::MAX_COLOR_TARGETS + 2]>;

#[derive(Debug)]
enum Command {
Draw {
Expand Down Expand Up @@ -474,10 +484,16 @@ enum Command {
dst_offset: wgt::BufferAddress,
},
ResetFramebuffer,
SetFramebufferAttachment {
BindAttachment {
attachment: u32,
view: TextureView,
},
ResolveAttachment {
attachment: u32,
dst: TextureView,
size: wgt::Extent3d,
},
InvalidateAttachments(InvalidatedAttachments),
SetDrawColorBuffers(u8),
ClearColorF(u32, [f32; 4]),
ClearColorU(u32, [u32; 4]),
Expand Down Expand Up @@ -511,6 +527,7 @@ enum Command {
attribute_desc: AttributeDesc,
},
SetProgram(glow::Program),
SetPrimitive(PrimitiveState),
SetBlendConstant([f32; 4]),
SetColorTarget {
draw_buffer_index: Option<u32>,
Expand Down
Loading

0 comments on commit af42298

Please sign in to comment.