mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
hal/gles: primitive state and framebuffer operations
This commit is contained in:
@@ -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"),
|
||||
@@ -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);
|
||||
@@ -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)?,
|
||||
|
||||
@@ -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],
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
@@ -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));
|
||||
@@ -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
|
||||
@@ -437,6 +469,19 @@ 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;
|
||||
@@ -444,6 +489,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
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(
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
@@ -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;
|
||||
@@ -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> {
|
||||
@@ -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,
|
||||
@@ -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,
|
||||
@@ -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();
|
||||
@@ -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 }
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>,
|
||||
@@ -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 {
|
||||
@@ -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]),
|
||||
@@ -511,6 +527,7 @@ enum Command {
|
||||
attribute_desc: AttributeDesc,
|
||||
},
|
||||
SetProgram(glow::Program),
|
||||
SetPrimitive(PrimitiveState),
|
||||
SetBlendConstant([f32; 4]),
|
||||
SetColorTarget {
|
||||
draw_buffer_index: Option<u32>,
|
||||
|
||||
@@ -26,6 +26,39 @@ impl super::Queue {
|
||||
gl.disable(glow::STENCIL_TEST);
|
||||
gl.disable(glow::SCISSOR_TEST);
|
||||
gl.disable(glow::BLEND);
|
||||
gl.disable(glow::CULL_FACE);
|
||||
gl.disable(glow::POLYGON_OFFSET_FILL);
|
||||
if self.features.contains(wgt::Features::DEPTH_CLAMPING) {
|
||||
gl.disable(glow::DEPTH_CLAMP);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn set_attachment(&self, fbo_target: u32, attachment: u32, view: &super::TextureView) {
|
||||
let gl = &self.shared.context;
|
||||
match view.inner {
|
||||
super::TextureInner::Renderbuffer { raw } => {
|
||||
gl.framebuffer_renderbuffer(fbo_target, attachment, glow::RENDERBUFFER, Some(raw));
|
||||
}
|
||||
super::TextureInner::Texture { raw, target } => {
|
||||
if is_3d_target(target) {
|
||||
gl.framebuffer_texture_layer(
|
||||
fbo_target,
|
||||
attachment,
|
||||
Some(raw),
|
||||
view.mip_levels.start as i32,
|
||||
view.array_layers.start as i32,
|
||||
);
|
||||
} else {
|
||||
gl.framebuffer_texture_2d(
|
||||
fbo_target,
|
||||
attachment,
|
||||
target,
|
||||
Some(raw),
|
||||
view.mip_levels.start as i32,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn process(&mut self, command: &C, data_bytes: &[u8], data_words: &[u32]) {
|
||||
@@ -329,38 +362,39 @@ impl super::Queue {
|
||||
gl.disable(glow::STENCIL_TEST);
|
||||
gl.disable(glow::SCISSOR_TEST);
|
||||
}
|
||||
C::SetFramebufferAttachment {
|
||||
C::BindAttachment {
|
||||
attachment,
|
||||
ref view,
|
||||
} => match view.inner {
|
||||
super::TextureInner::Renderbuffer { raw } => {
|
||||
gl.framebuffer_renderbuffer(
|
||||
glow::DRAW_FRAMEBUFFER,
|
||||
attachment,
|
||||
glow::RENDERBUFFER,
|
||||
Some(raw),
|
||||
);
|
||||
}
|
||||
super::TextureInner::Texture { raw, target } => {
|
||||
if is_3d_target(target) {
|
||||
gl.framebuffer_texture_layer(
|
||||
glow::DRAW_FRAMEBUFFER,
|
||||
attachment,
|
||||
Some(raw),
|
||||
view.mip_levels.start as i32,
|
||||
view.array_layers.start as i32,
|
||||
);
|
||||
} else {
|
||||
gl.framebuffer_texture_2d(
|
||||
glow::DRAW_FRAMEBUFFER,
|
||||
attachment,
|
||||
target,
|
||||
Some(raw),
|
||||
view.mip_levels.start as i32,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
} => {
|
||||
self.set_attachment(glow::DRAW_FRAMEBUFFER, attachment, view);
|
||||
}
|
||||
C::ResolveAttachment {
|
||||
attachment,
|
||||
ref dst,
|
||||
ref size,
|
||||
} => {
|
||||
gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(self.draw_fbo));
|
||||
gl.read_buffer(attachment);
|
||||
gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, Some(self.copy_fbo));
|
||||
self.set_attachment(glow::DRAW_FRAMEBUFFER, glow::COLOR_ATTACHMENT0, dst);
|
||||
gl.blit_framebuffer(
|
||||
0,
|
||||
0,
|
||||
size.width as i32,
|
||||
size.height as i32,
|
||||
0,
|
||||
0,
|
||||
size.width as i32,
|
||||
size.height as i32,
|
||||
glow::COLOR_BUFFER_BIT,
|
||||
glow::NEAREST,
|
||||
);
|
||||
gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None);
|
||||
gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, Some(self.draw_fbo));
|
||||
}
|
||||
C::InvalidateAttachments(ref list) => {
|
||||
gl.invalidate_framebuffer(glow::DRAW_FRAMEBUFFER, list);
|
||||
}
|
||||
C::SetDrawColorBuffers(count) => {
|
||||
let indices = (0..count as u32)
|
||||
.map(|i| glow::COLOR_ATTACHMENT0 + i)
|
||||
@@ -380,10 +414,10 @@ impl super::Queue {
|
||||
gl.clear_buffer_i32_slice(glow::COLOR, draw_buffer, &mut color);
|
||||
}
|
||||
C::ClearDepth(depth) => {
|
||||
gl.clear_buffer_depth_stencil(glow::DEPTH, 0, depth, 0);
|
||||
gl.clear_buffer_f32_slice(glow::DEPTH, 0, &mut [depth]);
|
||||
}
|
||||
C::ClearStencil(value) => {
|
||||
gl.clear_buffer_depth_stencil(glow::STENCIL, 0, 0.0, value as i32);
|
||||
gl.clear_buffer_i32_slice(glow::STENCIL, 0, &mut [value as i32]);
|
||||
}
|
||||
C::BufferBarrier(raw, usage) => {
|
||||
let mut flags = 0;
|
||||
@@ -502,7 +536,12 @@ impl super::Queue {
|
||||
gl.depth_mask(depth.mask);
|
||||
}
|
||||
C::SetDepthBias(bias) => {
|
||||
gl.polygon_offset(bias.constant as f32, bias.slope_scale);
|
||||
if bias.is_enabled() {
|
||||
gl.enable(glow::POLYGON_OFFSET_FILL);
|
||||
gl.polygon_offset(bias.constant as f32, bias.slope_scale);
|
||||
} else {
|
||||
gl.disable(glow::POLYGON_OFFSET_FILL);
|
||||
}
|
||||
}
|
||||
C::ConfigureDepthStencil(aspects) => {
|
||||
if aspects.contains(crate::FormatAspect::DEPTH) {
|
||||
@@ -519,6 +558,22 @@ impl super::Queue {
|
||||
C::SetProgram(program) => {
|
||||
gl.use_program(Some(program));
|
||||
}
|
||||
C::SetPrimitive(ref state) => {
|
||||
gl.front_face(state.front_face);
|
||||
if state.cull_face != 0 {
|
||||
gl.enable(glow::CULL_FACE);
|
||||
gl.cull_face(state.cull_face);
|
||||
} else {
|
||||
gl.disable(glow::CULL_FACE);
|
||||
}
|
||||
if self.features.contains(wgt::Features::DEPTH_CLAMPING) {
|
||||
if state.clamp_depth {
|
||||
gl.enable(glow::DEPTH_CLAMP);
|
||||
} else {
|
||||
gl.disable(glow::DEPTH_CLAMP);
|
||||
}
|
||||
}
|
||||
}
|
||||
C::SetBlendConstant(c) => {
|
||||
gl.blend_color(c[0], c[1], c[2], c[3]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user