mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 14:55:05 +00:00
hal/gles: stencil and vertex state
This commit is contained in:
parent
205327d3aa
commit
13b0a61dc8
@ -232,7 +232,8 @@ impl super::Adapter {
|
||||
0
|
||||
},
|
||||
max_vertex_buffers: gl.get_parameter_i32(glow::MAX_VERTEX_ATTRIB_BINDINGS) as u32,
|
||||
max_vertex_attributes: gl.get_parameter_i32(glow::MAX_VERTEX_ATTRIBS) as u32,
|
||||
max_vertex_attributes: (gl.get_parameter_i32(glow::MAX_VERTEX_ATTRIBS) as u32)
|
||||
.min(super::MAX_VERTEX_ATTRIBUTES as u32),
|
||||
max_vertex_buffer_array_stride: 2048,
|
||||
max_push_constant_size: 0,
|
||||
};
|
||||
|
@ -1,6 +1,26 @@
|
||||
use super::{conv, Command as C};
|
||||
use arrayvec::ArrayVec;
|
||||
use std::{mem, ops::Range};
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(Default)]
|
||||
struct Dirty: u32 {
|
||||
const VERTEX_BUFFERS = 0x0001;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub(super) struct State {
|
||||
topology: u32,
|
||||
index_format: wgt::IndexFormat,
|
||||
index_offset: wgt::BufferAddress,
|
||||
vertex_buffers: [super::VertexBufferDesc; crate::MAX_VERTEX_BUFFERS],
|
||||
vertex_attributes: ArrayVec<[super::AttributeDesc; super::MAX_VERTEX_ATTRIBUTES]>,
|
||||
stencil: super::StencilState,
|
||||
has_pass_label: bool,
|
||||
dirty: Dirty,
|
||||
}
|
||||
|
||||
impl super::CommandBuffer {
|
||||
fn clear(&mut self) {
|
||||
self.label = None;
|
||||
@ -16,9 +36,62 @@ impl super::CommandBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
impl super::CommandEncoder {
|
||||
fn rebind_stencil_func(&mut self) {
|
||||
fn make(s: &super::StencilSide, face: u32) -> C {
|
||||
C::SetStencilFunc {
|
||||
face,
|
||||
function: s.function,
|
||||
reference: s.reference,
|
||||
read_mask: s.mask_read,
|
||||
}
|
||||
}
|
||||
|
||||
let s = &self.state.stencil;
|
||||
if s.front.function == s.back.function
|
||||
&& s.front.mask_read == s.back.mask_read
|
||||
&& s.front.reference == s.back.reference
|
||||
{
|
||||
self.cmd_buffer
|
||||
.commands
|
||||
.push(make(&s.front, glow::FRONT_AND_BACK));
|
||||
} else {
|
||||
self.cmd_buffer.commands.push(make(&s.front, glow::FRONT));
|
||||
self.cmd_buffer.commands.push(make(&s.back, glow::BACK));
|
||||
}
|
||||
}
|
||||
|
||||
fn rebind_vertex_attributes(&mut self, first_instance: u32) {
|
||||
for attribute in self.state.vertex_attributes.iter() {
|
||||
let vb = self.state.vertex_buffers[attribute.buffer_index as usize].clone();
|
||||
|
||||
let mut vat = attribute.clone();
|
||||
vat.offset += vb.offset as u32;
|
||||
|
||||
if vb.step == wgt::InputStepMode::Instance {
|
||||
vat.offset += vb.stride * first_instance;
|
||||
}
|
||||
|
||||
self.cmd_buffer
|
||||
.commands
|
||||
.push(C::SetVertexAttribute(vat, vb));
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_draw(&mut self, first_instance: u32) {
|
||||
if first_instance != 0 {
|
||||
self.rebind_vertex_attributes(first_instance);
|
||||
self.state.dirty.set(Dirty::VERTEX_BUFFERS, true);
|
||||
} else if self.state.dirty.contains(Dirty::VERTEX_BUFFERS) {
|
||||
self.rebind_vertex_attributes(0);
|
||||
self.state.dirty.set(Dirty::VERTEX_BUFFERS, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
unsafe fn begin_encoding(&mut self, label: crate::Label) -> Result<(), crate::DeviceError> {
|
||||
self.state = super::CommandState::default();
|
||||
self.state = State::default();
|
||||
self.cmd_buffer.label = label.map(str::to_string);
|
||||
Ok(())
|
||||
}
|
||||
@ -63,18 +136,22 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let mut combined_usage = crate::TextureUse::empty();
|
||||
for bar in barriers {
|
||||
// GLES only synchronizes storage -> anything explicitly
|
||||
if !bar.usage.start.contains(crate::TextureUse::STORAGE_STORE) {
|
||||
continue;
|
||||
}
|
||||
let raw = match bar.texture.inner {
|
||||
super::TextureInner::Texture { raw, .. } => raw,
|
||||
super::TextureInner::Renderbuffer { .. } => continue,
|
||||
};
|
||||
// unlike buffers, there is no need for a concrete texture
|
||||
// object to be bound anywhere for a barrier
|
||||
combined_usage |= bar.usage.end;
|
||||
}
|
||||
|
||||
if !combined_usage.is_empty() {
|
||||
self.cmd_buffer
|
||||
.commands
|
||||
.push(C::TextureBarrier(raw, bar.usage.end));
|
||||
.push(C::TextureBarrier(combined_usage));
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,9 +312,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
}
|
||||
|
||||
// set the framebuffer
|
||||
self.cmd_buffer
|
||||
.commands
|
||||
.push(C::ResetFramebuffer(desc.extent));
|
||||
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 {
|
||||
@ -257,9 +332,22 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
});
|
||||
}
|
||||
|
||||
// set the draw buffers and states
|
||||
self.cmd_buffer
|
||||
.commands
|
||||
.push(C::SetDrawColorBuffers(desc.color_attachments.len() as u8));
|
||||
let rect = crate::Rect {
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: desc.extent.width as i32,
|
||||
h: desc.extent.height as i32,
|
||||
};
|
||||
self.cmd_buffer.commands.push(C::SetScissor(rect.clone()));
|
||||
self.cmd_buffer.commands.push(C::SetViewport {
|
||||
rect,
|
||||
depth: 0.0..1.0,
|
||||
});
|
||||
|
||||
// issue the clears
|
||||
for (i, cat) in desc.color_attachments.iter().enumerate() {
|
||||
if !cat.ops.contains(crate::AttachmentOp::LOAD) {
|
||||
@ -302,6 +390,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
self.cmd_buffer.commands.push(C::PopDebugGroup);
|
||||
self.state.has_pass_label = false;
|
||||
}
|
||||
self.state.dirty = Dirty::empty();
|
||||
}
|
||||
|
||||
unsafe fn set_bind_group(
|
||||
@ -335,6 +424,46 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
|
||||
unsafe fn set_render_pipeline(&mut self, pipeline: &super::RenderPipeline) {
|
||||
self.state.topology = conv::map_primitive_topology(pipeline.primitive.topology);
|
||||
self.state.dirty |= Dirty::VERTEX_BUFFERS;
|
||||
|
||||
self.state.vertex_attributes.clear();
|
||||
for vat in pipeline.vertex_attributes.iter() {
|
||||
self.state.vertex_attributes.push(vat.clone());
|
||||
}
|
||||
for (state_desc, pipe_desc) in self
|
||||
.state
|
||||
.vertex_buffers
|
||||
.iter_mut()
|
||||
.zip(pipeline.vertex_buffers.iter())
|
||||
{
|
||||
state_desc.step = pipe_desc.step;
|
||||
state_desc.stride = pipe_desc.stride;
|
||||
}
|
||||
|
||||
if let Some(ref stencil) = pipeline.stencil {
|
||||
self.state.stencil = stencil.clone();
|
||||
self.rebind_stencil_func();
|
||||
if stencil.front.ops == stencil.back.ops
|
||||
&& stencil.front.mask_write == stencil.back.mask_write
|
||||
{
|
||||
self.cmd_buffer.commands.push(C::SetStencilOps {
|
||||
face: glow::FRONT_AND_BACK,
|
||||
write_mask: stencil.front.mask_write,
|
||||
ops: stencil.front.ops.clone(),
|
||||
});
|
||||
} else {
|
||||
self.cmd_buffer.commands.push(C::SetStencilOps {
|
||||
face: glow::FRONT,
|
||||
write_mask: stencil.front.mask_write,
|
||||
ops: stencil.front.ops.clone(),
|
||||
});
|
||||
self.cmd_buffer.commands.push(C::SetStencilOps {
|
||||
face: glow::BACK,
|
||||
write_mask: stencil.back.mask_write,
|
||||
ops: stencil.back.ops.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn set_index_buffer<'a>(
|
||||
@ -353,10 +482,35 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
index: u32,
|
||||
binding: crate::BufferBinding<'a, super::Api>,
|
||||
) {
|
||||
self.state.dirty |= Dirty::VERTEX_BUFFERS;
|
||||
let vb = &mut self.state.vertex_buffers[index as usize];
|
||||
vb.raw = binding.buffer.raw;
|
||||
vb.offset = binding.offset;
|
||||
}
|
||||
unsafe fn set_viewport(&mut self, rect: &crate::Rect<f32>, depth: Range<f32>) {
|
||||
self.cmd_buffer.commands.push(C::SetViewport {
|
||||
rect: crate::Rect {
|
||||
x: rect.x as i32,
|
||||
y: rect.y as i32,
|
||||
w: rect.w as i32,
|
||||
h: rect.h as i32,
|
||||
},
|
||||
depth,
|
||||
});
|
||||
}
|
||||
unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect<u32>) {
|
||||
self.cmd_buffer.commands.push(C::SetScissor(crate::Rect {
|
||||
x: rect.x as i32,
|
||||
y: rect.y as i32,
|
||||
w: rect.w as i32,
|
||||
h: rect.h as i32,
|
||||
}));
|
||||
}
|
||||
unsafe fn set_stencil_reference(&mut self, value: u32) {
|
||||
self.state.stencil.front.reference = value;
|
||||
self.state.stencil.back.reference = value;
|
||||
self.rebind_stencil_func();
|
||||
}
|
||||
unsafe fn set_viewport(&mut self, rect: &crate::Rect<f32>, depth_range: Range<f32>) {}
|
||||
unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect<u32>) {}
|
||||
unsafe fn set_stencil_reference(&mut self, value: u32) {}
|
||||
unsafe fn set_blend_constants(&mut self, color: &wgt::Color) {}
|
||||
|
||||
unsafe fn draw(
|
||||
@ -366,7 +520,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
start_instance: u32,
|
||||
instance_count: u32,
|
||||
) {
|
||||
debug_assert_eq!(start_instance, 0);
|
||||
self.prepare_draw(start_instance);
|
||||
self.cmd_buffer.commands.push(C::Draw {
|
||||
topology: self.state.topology,
|
||||
start_vertex,
|
||||
@ -382,7 +536,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
start_instance: u32,
|
||||
instance_count: u32,
|
||||
) {
|
||||
debug_assert_eq!(start_instance, 0);
|
||||
self.prepare_draw(start_instance);
|
||||
let (index_size, index_type) = match self.state.index_format {
|
||||
wgt::IndexFormat::Uint16 => (2, glow::UNSIGNED_SHORT),
|
||||
wgt::IndexFormat::Uint32 => (4, glow::UNSIGNED_INT),
|
||||
@ -403,6 +557,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
offset: wgt::BufferAddress,
|
||||
draw_count: u32,
|
||||
) {
|
||||
self.prepare_draw(0);
|
||||
for draw in 0..draw_count as wgt::BufferAddress {
|
||||
let indirect_offset =
|
||||
offset + draw * mem::size_of::<wgt::DrawIndirectArgs>() as wgt::BufferAddress;
|
||||
@ -419,6 +574,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
offset: wgt::BufferAddress,
|
||||
draw_count: u32,
|
||||
) {
|
||||
self.prepare_draw(0);
|
||||
let index_type = match self.state.index_format {
|
||||
wgt::IndexFormat::Uint16 => glow::UNSIGNED_SHORT,
|
||||
wgt::IndexFormat::Uint32 => glow::UNSIGNED_INT,
|
||||
@ -469,6 +625,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
self.cmd_buffer.commands.push(C::PopDebugGroup);
|
||||
self.state.has_pass_label = false;
|
||||
}
|
||||
self.state.dirty = Dirty::empty();
|
||||
}
|
||||
|
||||
unsafe fn set_compute_pipeline(&mut self, pipeline: &super::ComputePipeline) {}
|
||||
|
@ -232,3 +232,44 @@ pub fn map_view_dimension(dim: wgt::TextureViewDimension) -> u32 {
|
||||
Tvd::D3 => glow::TEXTURE_3D,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_stencil_op(operation: wgt::StencilOperation) -> u32 {
|
||||
use wgt::StencilOperation as So;
|
||||
match operation {
|
||||
So::Keep => glow::KEEP,
|
||||
So::Zero => glow::ZERO,
|
||||
So::Replace => glow::REPLACE,
|
||||
So::Invert => glow::INVERT,
|
||||
So::IncrementClamp => glow::INCR,
|
||||
So::DecrementClamp => glow::DECR,
|
||||
So::IncrementWrap => glow::INCR_WRAP,
|
||||
So::DecrementWrap => glow::DECR_WRAP,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_stencil_ops(face: &wgt::StencilFaceState) -> super::StencilOps {
|
||||
super::StencilOps {
|
||||
pass: map_stencil_op(face.pass_op),
|
||||
fail: map_stencil_op(face.fail_op),
|
||||
depth_fail: map_stencil_op(face.depth_fail_op),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn map_stencil(state: &wgt::StencilState) -> super::StencilState {
|
||||
super::StencilState {
|
||||
front: super::StencilSide {
|
||||
function: map_compare_func(state.front.compare),
|
||||
mask_read: state.read_mask,
|
||||
mask_write: state.write_mask,
|
||||
reference: 0,
|
||||
ops: map_stencil_ops(&state.front),
|
||||
},
|
||||
back: super::StencilSide {
|
||||
function: map_compare_func(state.back.compare),
|
||||
mask_read: state.read_mask,
|
||||
mask_write: state.write_mask,
|
||||
reference: 0,
|
||||
ops: map_stencil_ops(&state.back),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -518,7 +518,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(),
|
||||
state: Default::default(),
|
||||
private_caps: self.shared.private_caps,
|
||||
})
|
||||
}
|
||||
@ -665,11 +665,16 @@ impl crate::Device<super::Api> for super::Device {
|
||||
);
|
||||
let inner = self.create_pipeline(shaders, desc.layout)?;
|
||||
|
||||
let attributes = {
|
||||
let gl = &self.shared.context;
|
||||
let (vertex_buffers, vertex_attributes) = {
|
||||
let mut buffers = Vec::new();
|
||||
let mut attributes = Vec::new();
|
||||
|
||||
for (index, vb_layout) in desc.vertex_buffers.iter().enumerate() {
|
||||
buffers.push(super::VertexBufferDesc {
|
||||
raw: 0,
|
||||
offset: 0,
|
||||
step: vb_layout.step_mode,
|
||||
stride: vb_layout.array_stride as u32,
|
||||
});
|
||||
for vat in vb_layout.attributes.iter() {
|
||||
let format_desc = conv::describe_vertex_format(vat.format);
|
||||
attributes.push(super::AttributeDesc {
|
||||
@ -680,15 +685,23 @@ impl crate::Device<super::Api> for super::Device {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
attributes.into_boxed_slice()
|
||||
(buffers.into_boxed_slice(), attributes.into_boxed_slice())
|
||||
};
|
||||
|
||||
Ok(super::RenderPipeline {
|
||||
inner,
|
||||
primitive: desc.primitive,
|
||||
attributes,
|
||||
depth: desc.depth_stencil.clone(),
|
||||
vertex_buffers,
|
||||
vertex_attributes,
|
||||
depth: desc.depth_stencil.as_ref().map(|ds| super::DepthState {
|
||||
function: conv::map_compare_func(ds.depth_compare),
|
||||
mask: ds.depth_write_enabled,
|
||||
}),
|
||||
depth_bias: desc.depth_stencil.as_ref().map(|ds| ds.bias),
|
||||
stencil: desc
|
||||
.depth_stencil
|
||||
.as_ref()
|
||||
.map(|ds| conv::map_stencil(&ds.stencil)),
|
||||
})
|
||||
}
|
||||
unsafe fn destroy_render_pipeline(&self, pipeline: super::RenderPipeline) {
|
||||
|
@ -22,6 +22,7 @@ pub struct Api;
|
||||
//Note: we can support more samplers if not every one of them is used at a time,
|
||||
// but it probably doesn't worth it.
|
||||
const MAX_TEXTURE_SLOTS: usize = 16;
|
||||
const MAX_VERTEX_ATTRIBUTES: usize = 16;
|
||||
|
||||
impl crate::Api for Api {
|
||||
type Instance = Instance;
|
||||
@ -159,6 +160,12 @@ enum VertexAttribKind {
|
||||
//Double, // glVertexAttribLPointer
|
||||
}
|
||||
|
||||
impl Default for VertexAttribKind {
|
||||
fn default() -> Self {
|
||||
Self::Float
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct TextureFormatDesc {
|
||||
internal: u32,
|
||||
@ -296,12 +303,14 @@ pub struct ShaderModule {
|
||||
naga: crate::NagaShader,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct VertexFormatDesc {
|
||||
element_count: i32,
|
||||
element_format: u32,
|
||||
attrib_kind: VertexAttribKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct AttributeDesc {
|
||||
location: u32,
|
||||
offset: u32,
|
||||
@ -309,6 +318,14 @@ struct AttributeDesc {
|
||||
format_desc: VertexFormatDesc,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct VertexBufferDesc {
|
||||
raw: glow::Buffer,
|
||||
offset: wgt::BufferAddress,
|
||||
step: wgt::InputStepMode,
|
||||
stride: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct UniformDesc {
|
||||
location: glow::UniformLocation,
|
||||
@ -326,13 +343,20 @@ struct PipelineInner {
|
||||
uniforms: Box<[UniformDesc]>,
|
||||
}
|
||||
|
||||
struct DepthState {
|
||||
function: u32,
|
||||
mask: bool,
|
||||
}
|
||||
|
||||
pub struct RenderPipeline {
|
||||
inner: PipelineInner,
|
||||
//blend_targets: Vec<pso::ColorBlendDesc>,
|
||||
attributes: Box<[AttributeDesc]>,
|
||||
//vertex_buffers: Box<[wgt::VertexBufferLayout]>,
|
||||
vertex_buffers: Box<[VertexBufferDesc]>,
|
||||
vertex_attributes: Box<[AttributeDesc]>,
|
||||
primitive: wgt::PrimitiveState,
|
||||
depth: Option<wgt::DepthStencilState>,
|
||||
depth: Option<DepthState>,
|
||||
depth_bias: Option<wgt::DepthBiasState>,
|
||||
stencil: Option<StencilState>,
|
||||
}
|
||||
|
||||
pub struct ComputePipeline {
|
||||
@ -387,6 +411,50 @@ struct TextureCopyInfo {
|
||||
texel_size: u8,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct StencilOps {
|
||||
pass: u32,
|
||||
fail: u32,
|
||||
depth_fail: u32,
|
||||
}
|
||||
|
||||
impl Default for StencilOps {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
pass: glow::KEEP,
|
||||
fail: glow::KEEP,
|
||||
depth_fail: glow::KEEP,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct StencilSide {
|
||||
function: u32,
|
||||
mask_read: u32,
|
||||
mask_write: u32,
|
||||
reference: u32,
|
||||
ops: StencilOps,
|
||||
}
|
||||
|
||||
impl Default for StencilSide {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
function: glow::ALWAYS,
|
||||
mask_read: 0xFF,
|
||||
mask_write: 0xFF,
|
||||
reference: 0,
|
||||
ops: StencilOps::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct StencilState {
|
||||
front: StencilSide,
|
||||
back: StencilSide,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Command {
|
||||
Draw {
|
||||
@ -463,7 +531,7 @@ enum Command {
|
||||
dst_target: BindTarget,
|
||||
dst_offset: wgt::BufferAddress,
|
||||
},
|
||||
ResetFramebuffer(wgt::Extent3d),
|
||||
ResetFramebuffer,
|
||||
SetFramebufferAttachment {
|
||||
attachment: u32,
|
||||
view: TextureView,
|
||||
@ -475,7 +543,24 @@ enum Command {
|
||||
ClearDepth(f32),
|
||||
ClearStencil(u32),
|
||||
BufferBarrier(glow::Buffer, crate::BufferUse),
|
||||
TextureBarrier(glow::Texture, crate::TextureUse),
|
||||
TextureBarrier(crate::TextureUse),
|
||||
SetViewport {
|
||||
rect: crate::Rect<i32>,
|
||||
depth: Range<f32>,
|
||||
},
|
||||
SetScissor(crate::Rect<i32>),
|
||||
SetStencilFunc {
|
||||
face: u32,
|
||||
function: u32,
|
||||
reference: u32,
|
||||
read_mask: u32,
|
||||
},
|
||||
SetStencilOps {
|
||||
face: u32,
|
||||
write_mask: u32,
|
||||
ops: StencilOps,
|
||||
},
|
||||
SetVertexAttribute(AttributeDesc, VertexBufferDesc),
|
||||
InsertDebugMarker(Range<u32>),
|
||||
PushDebugGroup(Range<u32>),
|
||||
PopDebugGroup,
|
||||
@ -489,20 +574,12 @@ pub struct CommandBuffer {
|
||||
data_words: Vec<u32>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct CommandState {
|
||||
topology: u32,
|
||||
index_format: wgt::IndexFormat,
|
||||
index_offset: wgt::BufferAddress,
|
||||
has_pass_label: bool,
|
||||
}
|
||||
|
||||
//TODO: we would have something like `Arc<typed_arena::Arena>`
|
||||
// here and in the command buffers. So that everything grows
|
||||
// inside the encoder and stays there until `reset_all`.
|
||||
|
||||
pub struct CommandEncoder {
|
||||
cmd_buffer: CommandBuffer,
|
||||
state: CommandState,
|
||||
state: command::State,
|
||||
private_caps: PrivateCapability,
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ impl super::Queue {
|
||||
gl.bind_buffer(dst_target, Some(dst));
|
||||
gl.buffer_sub_data_u8_slice(dst_target, dst_offset as i32, query_data);
|
||||
}
|
||||
C::ResetFramebuffer(extent) => {
|
||||
C::ResetFramebuffer => {
|
||||
gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, Some(self.draw_fbo));
|
||||
gl.framebuffer_texture_2d(
|
||||
glow::DRAW_FRAMEBUFFER,
|
||||
@ -317,8 +317,6 @@ impl super::Queue {
|
||||
gl.disable(glow::DEPTH_TEST);
|
||||
gl.disable(glow::STENCIL_TEST);
|
||||
gl.disable(glow::SCISSOR_TEST);
|
||||
gl.scissor(0, 0, extent.width as i32, extent.height as i32);
|
||||
gl.viewport(0, 0, extent.width as i32, extent.height as i32);
|
||||
}
|
||||
C::SetFramebufferAttachment {
|
||||
attachment,
|
||||
@ -409,7 +407,7 @@ impl super::Queue {
|
||||
}
|
||||
gl.memory_barrier(flags);
|
||||
}
|
||||
C::TextureBarrier(_raw, usage) => {
|
||||
C::TextureBarrier(usage) => {
|
||||
let mut flags = 0;
|
||||
if usage.contains(crate::TextureUse::SAMPLED) {
|
||||
flags |= glow::TEXTURE_FETCH_BARRIER_BIT;
|
||||
@ -431,6 +429,55 @@ impl super::Queue {
|
||||
}
|
||||
gl.memory_barrier(flags);
|
||||
}
|
||||
C::SetViewport {
|
||||
ref rect,
|
||||
ref depth,
|
||||
} => {
|
||||
gl.viewport(rect.x, rect.y, rect.w, rect.h);
|
||||
gl.depth_range_f32(depth.start, depth.end);
|
||||
}
|
||||
C::SetScissor(ref rect) => {
|
||||
gl.scissor(rect.x, rect.y, rect.w, rect.h);
|
||||
}
|
||||
C::SetStencilFunc {
|
||||
face,
|
||||
function,
|
||||
reference,
|
||||
read_mask,
|
||||
} => {
|
||||
gl.stencil_func_separate(face, function, reference as i32, read_mask);
|
||||
}
|
||||
C::SetStencilOps {
|
||||
face,
|
||||
write_mask,
|
||||
ref ops,
|
||||
} => {
|
||||
gl.stencil_mask_separate(face, write_mask);
|
||||
gl.stencil_op_separate(face, ops.fail, ops.depth_fail, ops.pass);
|
||||
}
|
||||
C::SetVertexAttribute(ref vat, ref vb) => {
|
||||
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vb.raw));
|
||||
let offset = vat.offset as i32 + vb.offset as i32;
|
||||
match vat.format_desc.attrib_kind {
|
||||
super::VertexAttribKind::Float => gl.vertex_attrib_pointer_f32(
|
||||
vat.location,
|
||||
vat.format_desc.element_count,
|
||||
vat.format_desc.element_format,
|
||||
true, // always normalized
|
||||
vb.stride as i32,
|
||||
offset,
|
||||
),
|
||||
super::VertexAttribKind::Integer => gl.vertex_attrib_pointer_i32(
|
||||
vat.location,
|
||||
vat.format_desc.element_count,
|
||||
vat.format_desc.element_format,
|
||||
vb.stride as i32,
|
||||
offset,
|
||||
),
|
||||
}
|
||||
gl.vertex_attrib_divisor(vat.location, vb.step as u32);
|
||||
gl.enable_vertex_attrib_array(vat.location);
|
||||
}
|
||||
C::InsertDebugMarker(ref range) => {
|
||||
let marker = extract_marker(data_bytes, range);
|
||||
gl.debug_message_insert(
|
||||
|
Loading…
Reference in New Issue
Block a user