mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-02-17 01:12:41 +00:00
hal/gles: pipeline creation
This commit is contained in:
parent
d29c450ec3
commit
d3d2ed5a9e
@ -169,6 +169,14 @@ impl super::Adapter {
|
||||
let extensions = gl.supported_extensions();
|
||||
log::info!("Extensions: {:?}", extensions);
|
||||
|
||||
let shading_language_version = {
|
||||
let sl_version = gl.get_parameter_string(glow::SHADING_LANGUAGE_VERSION);
|
||||
log::info!("SL version: {}", sl_version);
|
||||
let (sl_major, sl_minor) = Self::parse_version(&version).ok()?;
|
||||
let value = (sl_major * 100 + sl_minor * 10) as u16;
|
||||
naga::back::glsl::Version::Embedded(value)
|
||||
};
|
||||
|
||||
let mut features = wgt::Features::empty() | wgt::Features::NON_FILL_POLYGON_MODE;
|
||||
features.set(
|
||||
wgt::Features::DEPTH_CLAMPING,
|
||||
@ -240,6 +248,7 @@ impl super::Adapter {
|
||||
shared: Arc::new(super::AdapterShared {
|
||||
context: gl,
|
||||
private_caps,
|
||||
shading_language_version,
|
||||
}),
|
||||
},
|
||||
info: Self::make_info(vendor, renderer),
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::Command as C;
|
||||
use super::Resource; //TEMP
|
||||
use super::{conv, Command as C};
|
||||
use std::{mem, ops::Range};
|
||||
|
||||
impl super::CommandBuffer {
|
||||
@ -113,7 +113,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
dst: dst_raw,
|
||||
dst_target,
|
||||
dst_info: super::TextureCopyInfo {
|
||||
external_format: dst.format_desc.tex_external,
|
||||
external_format: dst.format_desc.external,
|
||||
data_type: dst.format_desc.data_type,
|
||||
texel_size: dst.format_info.block_size,
|
||||
},
|
||||
@ -142,7 +142,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
src: src_raw,
|
||||
src_target,
|
||||
src_info: super::TextureCopyInfo {
|
||||
external_format: src.format_desc.tex_external,
|
||||
external_format: src.format_desc.external,
|
||||
data_type: src.format_desc.data_type,
|
||||
texel_size: src.format_info.block_size,
|
||||
},
|
||||
@ -200,7 +200,9 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
self.cmd_buffer.commands.push(C::PopDebugGroup);
|
||||
}
|
||||
|
||||
unsafe fn set_render_pipeline(&mut self, pipeline: &Resource) {}
|
||||
unsafe fn set_render_pipeline(&mut self, pipeline: &super::RenderPipeline) {
|
||||
self.state.topology = conv::map_primitive_topology(pipeline.primitive.topology);
|
||||
}
|
||||
|
||||
unsafe fn set_index_buffer<'a>(
|
||||
&mut self,
|
||||
@ -233,7 +235,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
) {
|
||||
debug_assert_eq!(start_instance, 0);
|
||||
self.cmd_buffer.commands.push(C::Draw {
|
||||
primitive: self.state.primitive,
|
||||
topology: self.state.topology,
|
||||
start_vertex,
|
||||
vertex_count,
|
||||
instance_count,
|
||||
@ -254,7 +256,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
};
|
||||
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,
|
||||
topology: self.state.topology,
|
||||
index_type,
|
||||
index_offset,
|
||||
index_count,
|
||||
@ -272,7 +274,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
let indirect_offset =
|
||||
offset + draw * mem::size_of::<wgt::DrawIndirectArgs>() as wgt::BufferAddress;
|
||||
self.cmd_buffer.commands.push(C::DrawIndirect {
|
||||
primitive: self.state.primitive,
|
||||
topology: self.state.topology,
|
||||
indirect_buf: buffer.raw,
|
||||
indirect_offset,
|
||||
});
|
||||
@ -292,7 +294,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
let indirect_offset = offset
|
||||
+ draw * mem::size_of::<wgt::DrawIndexedIndirectArgs>() as wgt::BufferAddress;
|
||||
self.cmd_buffer.commands.push(C::DrawIndexedIndirect {
|
||||
primitive: self.state.primitive,
|
||||
topology: self.state.topology,
|
||||
index_type,
|
||||
indirect_buf: buffer.raw,
|
||||
indirect_offset,
|
||||
@ -325,7 +327,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor) {}
|
||||
unsafe fn end_compute_pass(&mut self) {}
|
||||
|
||||
unsafe fn set_compute_pipeline(&mut self, pipeline: &Resource) {}
|
||||
unsafe fn set_compute_pipeline(&mut self, pipeline: &super::ComputePipeline) {}
|
||||
|
||||
unsafe fn dispatch(&mut self, count: [u32; 3]) {
|
||||
self.cmd_buffer.commands.push(C::Dispatch(count));
|
||||
|
@ -1,163 +1,64 @@
|
||||
impl super::AdapterShared {
|
||||
pub(super) fn describe_texture_format(
|
||||
&self,
|
||||
format: wgt::TextureFormat,
|
||||
) -> super::FormatDescription {
|
||||
use super::VertexAttribKind as Vak;
|
||||
texture_format: wgt::TextureFormat,
|
||||
) -> super::TextureFormatDesc {
|
||||
use wgt::TextureFormat as Tf;
|
||||
|
||||
let (tex_internal, tex_external, data_type, num_components, va_kind) = match format {
|
||||
Tf::R8Unorm => (glow::R8, glow::RED, glow::UNSIGNED_BYTE, 1, Vak::Float),
|
||||
Tf::R8Snorm => (glow::R8, glow::RED, glow::BYTE, 1, Vak::Float),
|
||||
Tf::R8Uint => (
|
||||
glow::R8UI,
|
||||
glow::RED_INTEGER,
|
||||
glow::UNSIGNED_BYTE,
|
||||
1,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::R8Sint => (glow::R8I, glow::RED_INTEGER, glow::BYTE, 1, Vak::Integer),
|
||||
Tf::R16Uint => (
|
||||
glow::R16UI,
|
||||
glow::RED_INTEGER,
|
||||
glow::UNSIGNED_SHORT,
|
||||
1,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::R16Sint => (glow::R16I, glow::RED_INTEGER, glow::SHORT, 1, Vak::Integer),
|
||||
Tf::R16Float => (glow::R16F, glow::RED, glow::UNSIGNED_SHORT, 1, Vak::Float),
|
||||
Tf::Rg8Unorm => (glow::RG8, glow::RG, glow::UNSIGNED_BYTE, 2, Vak::Float),
|
||||
Tf::Rg8Snorm => (glow::RG8, glow::RG, glow::BYTE, 2, Vak::Float),
|
||||
Tf::Rg8Uint => (
|
||||
glow::RG8UI,
|
||||
glow::RG_INTEGER,
|
||||
glow::UNSIGNED_BYTE,
|
||||
2,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::Rg8Sint => (glow::RG8I, glow::RG_INTEGER, glow::BYTE, 2, Vak::Integer),
|
||||
Tf::R32Uint => (
|
||||
glow::R32UI,
|
||||
glow::RED_INTEGER,
|
||||
glow::UNSIGNED_INT,
|
||||
1,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::R32Sint => (glow::R32I, glow::RED_INTEGER, glow::INT, 1, Vak::Integer),
|
||||
Tf::R32Float => (glow::R32F, glow::RED, glow::FLOAT, 1, Vak::Float),
|
||||
Tf::Rg16Uint => (
|
||||
glow::RG16UI,
|
||||
glow::RG_INTEGER,
|
||||
glow::UNSIGNED_SHORT,
|
||||
2,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::Rg16Sint => (glow::RG16I, glow::RG_INTEGER, glow::SHORT, 2, Vak::Integer),
|
||||
Tf::Rg16Float => (glow::RG16F, glow::RG, glow::UNSIGNED_SHORT, 2, Vak::Float),
|
||||
Tf::Rgba8Unorm => (glow::RGBA8, glow::RGBA, glow::UNSIGNED_BYTE, 4, Vak::Float),
|
||||
Tf::Rgba8UnormSrgb => (
|
||||
glow::SRGB8_ALPHA8,
|
||||
glow::RGBA,
|
||||
glow::UNSIGNED_BYTE,
|
||||
4,
|
||||
Vak::Float,
|
||||
),
|
||||
Tf::Bgra8UnormSrgb => (
|
||||
glow::SRGB8_ALPHA8,
|
||||
glow::RGBA,
|
||||
glow::UNSIGNED_BYTE,
|
||||
4,
|
||||
Vak::Float,
|
||||
), //TODO?
|
||||
Tf::Rgba8Snorm => (glow::RGBA8, glow::RGBA, glow::BYTE, 4, Vak::Float),
|
||||
Tf::Bgra8Unorm => (glow::RGBA8, glow::BGRA, glow::UNSIGNED_BYTE, 4, Vak::Float),
|
||||
Tf::Rgba8Uint => (
|
||||
glow::RGBA8UI,
|
||||
glow::RGBA_INTEGER,
|
||||
glow::UNSIGNED_BYTE,
|
||||
4,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::Rgba8Sint => (
|
||||
glow::RGBA8I,
|
||||
glow::RGBA_INTEGER,
|
||||
glow::BYTE,
|
||||
4,
|
||||
Vak::Integer,
|
||||
),
|
||||
let (internal, external, data_type) = match texture_format {
|
||||
Tf::R8Unorm => (glow::R8, glow::RED, glow::UNSIGNED_BYTE),
|
||||
Tf::R8Snorm => (glow::R8, glow::RED, glow::BYTE),
|
||||
Tf::R8Uint => (glow::R8UI, glow::RED_INTEGER, glow::UNSIGNED_BYTE),
|
||||
Tf::R8Sint => (glow::R8I, glow::RED_INTEGER, glow::BYTE),
|
||||
Tf::R16Uint => (glow::R16UI, glow::RED_INTEGER, glow::UNSIGNED_SHORT),
|
||||
Tf::R16Sint => (glow::R16I, glow::RED_INTEGER, glow::SHORT),
|
||||
Tf::R16Float => (glow::R16F, glow::RED, glow::HALF_FLOAT),
|
||||
Tf::Rg8Unorm => (glow::RG8, glow::RG, glow::UNSIGNED_BYTE),
|
||||
Tf::Rg8Snorm => (glow::RG8, glow::RG, glow::BYTE),
|
||||
Tf::Rg8Uint => (glow::RG8UI, glow::RG_INTEGER, glow::UNSIGNED_BYTE),
|
||||
Tf::Rg8Sint => (glow::RG8I, glow::RG_INTEGER, glow::BYTE),
|
||||
Tf::R32Uint => (glow::R32UI, glow::RED_INTEGER, glow::UNSIGNED_INT),
|
||||
Tf::R32Sint => (glow::R32I, glow::RED_INTEGER, glow::INT),
|
||||
Tf::R32Float => (glow::R32F, glow::RED, glow::FLOAT),
|
||||
Tf::Rg16Uint => (glow::RG16UI, glow::RG_INTEGER, glow::UNSIGNED_SHORT),
|
||||
Tf::Rg16Sint => (glow::RG16I, glow::RG_INTEGER, glow::SHORT),
|
||||
Tf::Rg16Float => (glow::RG16F, glow::RG, glow::HALF_FLOAT),
|
||||
Tf::Rgba8Unorm => (glow::RGBA8, glow::RGBA, glow::UNSIGNED_BYTE),
|
||||
Tf::Rgba8UnormSrgb => (glow::SRGB8_ALPHA8, glow::RGBA, glow::UNSIGNED_BYTE),
|
||||
Tf::Bgra8UnormSrgb => (glow::SRGB8_ALPHA8, glow::RGBA, glow::UNSIGNED_BYTE), //TODO?
|
||||
Tf::Rgba8Snorm => (glow::RGBA8, glow::RGBA, glow::BYTE),
|
||||
Tf::Bgra8Unorm => (glow::RGBA8, glow::BGRA, glow::UNSIGNED_BYTE),
|
||||
Tf::Rgba8Uint => (glow::RGBA8UI, glow::RGBA_INTEGER, glow::UNSIGNED_BYTE),
|
||||
Tf::Rgba8Sint => (glow::RGBA8I, glow::RGBA_INTEGER, glow::BYTE),
|
||||
Tf::Rgb10a2Unorm => (
|
||||
glow::RGB10_A2,
|
||||
glow::RGBA,
|
||||
glow::UNSIGNED_INT_2_10_10_10_REV,
|
||||
1,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::Rg11b10Float => (
|
||||
glow::R11F_G11F_B10F,
|
||||
glow::RGB,
|
||||
glow::UNSIGNED_INT_10F_11F_11F_REV,
|
||||
1,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::Rg32Uint => (
|
||||
glow::RG32UI,
|
||||
glow::RG_INTEGER,
|
||||
glow::UNSIGNED_INT,
|
||||
2,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::Rg32Sint => (glow::RG32I, glow::RG_INTEGER, glow::INT, 2, Vak::Integer),
|
||||
Tf::Rg32Float => (glow::RG32F, glow::RG, glow::FLOAT, 2, Vak::Float),
|
||||
Tf::Rgba16Uint => (
|
||||
glow::RGBA16UI,
|
||||
glow::RGBA_INTEGER,
|
||||
glow::UNSIGNED_SHORT,
|
||||
4,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::Rgba16Sint => (
|
||||
glow::RGBA16I,
|
||||
glow::RGBA_INTEGER,
|
||||
glow::SHORT,
|
||||
4,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::Rgba16Float => (glow::RGBA16F, glow::RG, glow::UNSIGNED_SHORT, 4, Vak::Float),
|
||||
Tf::Rgba32Uint => (
|
||||
glow::RGBA32UI,
|
||||
glow::RGBA_INTEGER,
|
||||
glow::UNSIGNED_INT,
|
||||
4,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::Rgba32Sint => (
|
||||
glow::RGBA32I,
|
||||
glow::RGBA_INTEGER,
|
||||
glow::INT,
|
||||
4,
|
||||
Vak::Integer,
|
||||
),
|
||||
Tf::Rgba32Float => (glow::RGBA32F, glow::RGBA, glow::FLOAT, 4, Vak::Float),
|
||||
Tf::Depth32Float => (
|
||||
glow::DEPTH_COMPONENT32F,
|
||||
glow::DEPTH_COMPONENT,
|
||||
glow::FLOAT,
|
||||
1,
|
||||
Vak::Float,
|
||||
),
|
||||
Tf::Rg32Uint => (glow::RG32UI, glow::RG_INTEGER, glow::UNSIGNED_INT),
|
||||
Tf::Rg32Sint => (glow::RG32I, glow::RG_INTEGER, glow::INT),
|
||||
Tf::Rg32Float => (glow::RG32F, glow::RG, glow::FLOAT),
|
||||
Tf::Rgba16Uint => (glow::RGBA16UI, glow::RGBA_INTEGER, glow::UNSIGNED_SHORT),
|
||||
Tf::Rgba16Sint => (glow::RGBA16I, glow::RGBA_INTEGER, glow::SHORT),
|
||||
Tf::Rgba16Float => (glow::RGBA16F, glow::RG, glow::HALF_FLOAT),
|
||||
Tf::Rgba32Uint => (glow::RGBA32UI, glow::RGBA_INTEGER, glow::UNSIGNED_INT),
|
||||
Tf::Rgba32Sint => (glow::RGBA32I, glow::RGBA_INTEGER, glow::INT),
|
||||
Tf::Rgba32Float => (glow::RGBA32F, glow::RGBA, glow::FLOAT),
|
||||
Tf::Depth32Float => (glow::DEPTH_COMPONENT32F, glow::DEPTH_COMPONENT, glow::FLOAT),
|
||||
Tf::Depth24Plus => (
|
||||
glow::DEPTH_COMPONENT24,
|
||||
glow::DEPTH_COMPONENT,
|
||||
glow::UNSIGNED_NORMALIZED,
|
||||
2,
|
||||
Vak::Float,
|
||||
),
|
||||
Tf::Depth24PlusStencil8 => (
|
||||
glow::DEPTH24_STENCIL8,
|
||||
glow::DEPTH_COMPONENT,
|
||||
glow::UNSIGNED_INT,
|
||||
2,
|
||||
Vak::Float,
|
||||
),
|
||||
Tf::Bc1RgbaUnorm
|
||||
| Tf::Bc1RgbaUnormSrgb
|
||||
@ -211,16 +112,59 @@ impl super::AdapterShared {
|
||||
| Tf::Astc12x12RgbaUnormSrgb => unimplemented!(),
|
||||
};
|
||||
|
||||
super::FormatDescription {
|
||||
tex_internal,
|
||||
tex_external,
|
||||
super::TextureFormatDesc {
|
||||
internal,
|
||||
external,
|
||||
data_type,
|
||||
num_components,
|
||||
va_kind,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn describe_vertex_format(vertex_format: wgt::VertexFormat) -> super::VertexFormatDesc {
|
||||
use super::VertexAttribKind as Vak;
|
||||
use wgt::VertexFormat as Vf;
|
||||
|
||||
let (element_count, element_format, attrib_kind) = match vertex_format {
|
||||
Vf::Unorm8x2 => (2, glow::UNSIGNED_BYTE, Vak::Float),
|
||||
Vf::Snorm8x2 => (2, glow::BYTE, Vak::Float),
|
||||
Vf::Uint8x2 => (2, glow::UNSIGNED_BYTE, Vak::Integer),
|
||||
Vf::Sint8x2 => (2, glow::BYTE, Vak::Integer),
|
||||
Vf::Unorm8x4 => (4, glow::UNSIGNED_BYTE, Vak::Float),
|
||||
Vf::Snorm8x4 => (4, glow::BYTE, Vak::Float),
|
||||
Vf::Uint8x4 => (4, glow::UNSIGNED_BYTE, Vak::Integer),
|
||||
Vf::Sint8x4 => (4, glow::BYTE, Vak::Integer),
|
||||
Vf::Unorm16x2 => (2, glow::UNSIGNED_SHORT, Vak::Float),
|
||||
Vf::Snorm16x2 => (2, glow::SHORT, Vak::Float),
|
||||
Vf::Uint16x2 => (2, glow::UNSIGNED_SHORT, Vak::Integer),
|
||||
Vf::Sint16x2 => (2, glow::SHORT, Vak::Integer),
|
||||
Vf::Float16x2 => (2, glow::HALF_FLOAT, Vak::Float),
|
||||
Vf::Unorm16x4 => (4, glow::UNSIGNED_SHORT, Vak::Float),
|
||||
Vf::Snorm16x4 => (4, glow::SHORT, Vak::Float),
|
||||
Vf::Uint16x4 => (4, glow::UNSIGNED_SHORT, Vak::Integer),
|
||||
Vf::Sint16x4 => (4, glow::SHORT, Vak::Integer),
|
||||
Vf::Float16x4 => (4, glow::HALF_FLOAT, Vak::Float),
|
||||
Vf::Uint32 => (1, glow::UNSIGNED_INT, Vak::Integer),
|
||||
Vf::Sint32 => (1, glow::INT, Vak::Integer),
|
||||
Vf::Float32 => (1, glow::FLOAT, Vak::Float),
|
||||
Vf::Uint32x2 => (2, glow::UNSIGNED_INT, Vak::Integer),
|
||||
Vf::Sint32x2 => (2, glow::INT, Vak::Integer),
|
||||
Vf::Float32x2 => (2, glow::FLOAT, Vak::Float),
|
||||
Vf::Uint32x3 => (3, glow::UNSIGNED_INT, Vak::Integer),
|
||||
Vf::Sint32x3 => (3, glow::INT, Vak::Integer),
|
||||
Vf::Float32x3 => (3, glow::FLOAT, Vak::Float),
|
||||
Vf::Uint32x4 => (4, glow::UNSIGNED_INT, Vak::Integer),
|
||||
Vf::Sint32x4 => (4, glow::INT, Vak::Integer),
|
||||
Vf::Float32x4 => (4, glow::FLOAT, Vak::Float),
|
||||
Vf::Float64 | Vf::Float64x2 | Vf::Float64x3 | Vf::Float64x4 => unimplemented!(),
|
||||
};
|
||||
|
||||
super::VertexFormatDesc {
|
||||
element_count,
|
||||
element_format,
|
||||
attrib_kind,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_filter_modes(
|
||||
min: wgt::FilterMode,
|
||||
mag: wgt::FilterMode,
|
||||
@ -266,3 +210,14 @@ pub fn map_compare_func(fun: wgt::CompareFunction) -> u32 {
|
||||
Cf::Always => glow::ALWAYS,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_primitive_topology(topology: wgt::PrimitiveTopology) -> u32 {
|
||||
use wgt::PrimitiveTopology as Pt;
|
||||
match topology {
|
||||
Pt::PointList => glow::POINTS,
|
||||
Pt::LineList => glow::LINES,
|
||||
Pt::LineStrip => glow::LINE_STRIP,
|
||||
Pt::TriangleList => glow::TRIANGLES,
|
||||
Pt::TriangleStrip => glow::TRIANGLE_STRIP,
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,259 @@
|
||||
use super::{DeviceResult, Resource}; //TEMP
|
||||
use super::conv;
|
||||
use super::Resource; //TEMP
|
||||
use crate::util::map_naga_stage;
|
||||
use glow::HasContext;
|
||||
use std::{convert::TryInto, ptr::NonNull, sync::Arc};
|
||||
use std::{convert::TryInto, iter, ptr::NonNull, sync::Arc};
|
||||
|
||||
type ShaderStage<'a> = (
|
||||
naga::ShaderStage,
|
||||
&'a crate::ProgrammableStage<'a, super::Api>,
|
||||
);
|
||||
type NameBindingMap = fxhash::FxHashMap<String, (super::BindingRegister, u8)>;
|
||||
|
||||
struct CompilationContext<'a> {
|
||||
layout: &'a super::PipelineLayout,
|
||||
sampler_map: &'a mut super::SamplerBindMap,
|
||||
name_binding_map: &'a mut NameBindingMap,
|
||||
}
|
||||
|
||||
impl CompilationContext<'_> {
|
||||
fn consume_reflection(
|
||||
self,
|
||||
module: &naga::Module,
|
||||
ep_info: &naga::valid::FunctionInfo,
|
||||
reflection_info: naga::back::glsl::ReflectionInfo,
|
||||
) {
|
||||
for (handle, var) in module.global_variables.iter() {
|
||||
if ep_info[handle].is_empty() {
|
||||
continue;
|
||||
}
|
||||
let register = match var.class {
|
||||
naga::StorageClass::Uniform => super::BindingRegister::UniformBuffers,
|
||||
naga::StorageClass::Storage => super::BindingRegister::StorageBuffers,
|
||||
_ => continue,
|
||||
};
|
||||
//TODO: make Naga reflect all the names, not just textures
|
||||
let br = var.binding.as_ref().unwrap();
|
||||
let slot = self.layout.get_slot(br);
|
||||
|
||||
let name = reflection_info.uniforms[&handle].clone();
|
||||
log::debug!("Rebind buffer: {:?} -> {}", var.name.as_ref(), &name);
|
||||
self.name_binding_map.insert(name, (register, slot));
|
||||
}
|
||||
|
||||
for (name, mapping) in reflection_info.texture_mapping {
|
||||
let tex_br = module.global_variables[mapping.texture]
|
||||
.binding
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let texture_linear_index = self.layout.get_slot(tex_br);
|
||||
|
||||
self.name_binding_map.insert(
|
||||
name,
|
||||
(super::BindingRegister::Textures, texture_linear_index),
|
||||
);
|
||||
if let Some(sampler_handle) = mapping.sampler {
|
||||
let sam_br = module.global_variables[sampler_handle]
|
||||
.binding
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let sampler_linear_index = self.layout.get_slot(sam_br);
|
||||
self.sampler_map[texture_linear_index as usize] = Some(sampler_linear_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Device {
|
||||
unsafe fn compile_shader(
|
||||
&self,
|
||||
shader: &str,
|
||||
naga_stage: naga::ShaderStage,
|
||||
) -> Result<glow::Shader, crate::PipelineError> {
|
||||
let gl = &self.shared.context;
|
||||
let target = match naga_stage {
|
||||
naga::ShaderStage::Vertex => glow::VERTEX_SHADER,
|
||||
naga::ShaderStage::Fragment => glow::FRAGMENT_SHADER,
|
||||
naga::ShaderStage::Compute => glow::COMPUTE_SHADER,
|
||||
};
|
||||
|
||||
let raw = gl.create_shader(target).unwrap();
|
||||
gl.shader_source(raw, shader);
|
||||
gl.compile_shader(raw);
|
||||
|
||||
log::info!("\tCompiled shader {:?}", raw);
|
||||
|
||||
let compiled_ok = gl.get_shader_compile_status(raw);
|
||||
let msg = gl.get_shader_info_log(raw);
|
||||
if compiled_ok {
|
||||
if !msg.is_empty() {
|
||||
log::warn!("\tCompile: {}", msg);
|
||||
}
|
||||
Ok(raw)
|
||||
} else {
|
||||
Err(crate::PipelineError::Linkage(
|
||||
map_naga_stage(naga_stage),
|
||||
msg,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn create_shader(
|
||||
&self,
|
||||
naga_stage: naga::ShaderStage,
|
||||
stage: &crate::ProgrammableStage<super::Api>,
|
||||
context: CompilationContext,
|
||||
) -> Result<glow::Shader, crate::PipelineError> {
|
||||
use naga::back::glsl;
|
||||
let options = glsl::Options {
|
||||
version: self.shared.shading_language_version,
|
||||
shader_stage: naga_stage,
|
||||
entry_point: stage.entry_point.to_string(),
|
||||
};
|
||||
|
||||
let shader = &stage.module.naga;
|
||||
let entry_point_index = (&shader.module.entry_points)
|
||||
.into_iter()
|
||||
.position(|ep| ep.name.as_str() == stage.entry_point)
|
||||
.ok_or(crate::PipelineError::EntryPoint(naga_stage))?;
|
||||
|
||||
let mut output = String::new();
|
||||
let mut writer = glsl::Writer::new(&mut output, &shader.module, &shader.info, &options)
|
||||
.map_err(|e| {
|
||||
let msg = format!("{}", e);
|
||||
crate::PipelineError::Linkage(map_naga_stage(naga_stage), msg)
|
||||
})?;
|
||||
|
||||
let reflection_info = writer.write().map_err(|e| {
|
||||
let msg = format!("{}", e);
|
||||
crate::PipelineError::Linkage(map_naga_stage(naga_stage), msg)
|
||||
})?;
|
||||
|
||||
log::debug!("Naga generated shader:\n{}", output);
|
||||
|
||||
context.consume_reflection(
|
||||
&shader.module,
|
||||
shader.info.get_entry_point(entry_point_index),
|
||||
reflection_info,
|
||||
);
|
||||
|
||||
unsafe { self.compile_shader(&output, naga_stage) }
|
||||
}
|
||||
|
||||
unsafe fn create_pipeline<'a, I: Iterator<Item = ShaderStage<'a>>>(
|
||||
&self,
|
||||
shaders: I,
|
||||
layout: &super::PipelineLayout,
|
||||
) -> Result<super::PipelineInner, crate::PipelineError> {
|
||||
let gl = &self.shared.context;
|
||||
let program = gl.create_program().unwrap();
|
||||
|
||||
let mut name_binding_map = NameBindingMap::default();
|
||||
let mut sampler_map = [None; super::MAX_TEXTURE_SLOTS];
|
||||
let mut has_stages = wgt::ShaderStage::empty();
|
||||
let mut shaders_to_delete = arrayvec::ArrayVec::<[_; 3]>::new();
|
||||
|
||||
for (naga_stage, stage) in shaders {
|
||||
has_stages |= map_naga_stage(naga_stage);
|
||||
let context = CompilationContext {
|
||||
layout,
|
||||
sampler_map: &mut sampler_map,
|
||||
name_binding_map: &mut name_binding_map,
|
||||
};
|
||||
|
||||
let shader = self.create_shader(naga_stage, stage, context)?;
|
||||
shaders_to_delete.push(shader);
|
||||
}
|
||||
|
||||
// Create empty fragment shader if only vertex shader is present
|
||||
if has_stages == wgt::ShaderStage::VERTEX {
|
||||
let version = match self.shared.shading_language_version {
|
||||
naga::back::glsl::Version::Embedded(v) => v,
|
||||
naga::back::glsl::Version::Desktop(_) => unreachable!(),
|
||||
};
|
||||
let shader_src = format!("#version {} es \n void main(void) {{}}", version,);
|
||||
log::info!("Only vertex shader is present. Creating an empty fragment shader",);
|
||||
let shader = self.compile_shader(&shader_src, naga::ShaderStage::Fragment)?;
|
||||
shaders_to_delete.push(shader);
|
||||
}
|
||||
|
||||
for &shader in shaders_to_delete.iter() {
|
||||
gl.attach_shader(program, shader);
|
||||
}
|
||||
gl.link_program(program);
|
||||
|
||||
for shader in shaders_to_delete {
|
||||
gl.delete_shader(shader);
|
||||
}
|
||||
|
||||
log::info!("\tLinked program {:?}", program);
|
||||
|
||||
let linked_ok = gl.get_program_link_status(program);
|
||||
let msg = gl.get_program_info_log(program);
|
||||
if !linked_ok {
|
||||
return Err(crate::PipelineError::Linkage(has_stages, msg));
|
||||
}
|
||||
if !msg.is_empty() {
|
||||
log::warn!("\tLink: {}", msg);
|
||||
}
|
||||
|
||||
if !self
|
||||
.shared
|
||||
.private_caps
|
||||
.contains(super::PrivateCapability::EXPLICIT_LAYOUTS_IN_SHADER)
|
||||
{
|
||||
gl.use_program(Some(program));
|
||||
for (ref name, (register, slot)) in name_binding_map {
|
||||
log::trace!("Get binding {:?} from program {:?}", name, program);
|
||||
match register {
|
||||
super::BindingRegister::Textures => {
|
||||
let loc = gl.get_uniform_location(program, name).unwrap();
|
||||
gl.uniform_1_i32(Some(&loc), slot as _);
|
||||
}
|
||||
super::BindingRegister::UniformBuffers => {
|
||||
let index = gl.get_uniform_block_index(program, name).unwrap();
|
||||
gl.uniform_block_binding(program, index, slot as _);
|
||||
}
|
||||
super::BindingRegister::StorageBuffers => {
|
||||
let index = gl.get_shader_storage_block_index(program, name).unwrap();
|
||||
gl.shader_storage_block_binding(program, index, slot as _);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let uniforms = {
|
||||
let count = gl.get_active_uniforms(program);
|
||||
let mut offset = 0;
|
||||
let mut uniforms = Vec::new();
|
||||
|
||||
for uniform in 0..count {
|
||||
let glow::ActiveUniform { size, utype, name } =
|
||||
gl.get_active_uniform(program, uniform).unwrap();
|
||||
|
||||
if let Some(location) = gl.get_uniform_location(program, &name) {
|
||||
// Sampler2D won't show up in UniformLocation and the only other uniforms
|
||||
// should be push constants
|
||||
uniforms.push(super::UniformDesc {
|
||||
location,
|
||||
offset,
|
||||
utype,
|
||||
});
|
||||
|
||||
offset += size as u32;
|
||||
}
|
||||
}
|
||||
|
||||
uniforms.into_boxed_slice()
|
||||
};
|
||||
|
||||
Ok(super::PipelineInner {
|
||||
program,
|
||||
sampler_map,
|
||||
uniforms,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Device<super::Api> for super::Device {
|
||||
unsafe fn exit(self) {
|
||||
@ -76,7 +329,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
is_coherent: buffer.map_flags & glow::MAP_COHERENT_BIT != 0,
|
||||
})
|
||||
}
|
||||
unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> DeviceResult<()> {
|
||||
unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> Result<(), crate::DeviceError> {
|
||||
let gl = &self.shared.context;
|
||||
gl.bind_buffer(buffer.target, Some(buffer.raw));
|
||||
gl.unmap_buffer(buffer.target);
|
||||
@ -131,14 +384,14 @@ impl crate::Device<super::Api> for super::Device {
|
||||
gl.renderbuffer_storage_multisample(
|
||||
glow::RENDERBUFFER,
|
||||
desc.sample_count as i32,
|
||||
format_desc.tex_internal,
|
||||
format_desc.internal,
|
||||
desc.size.width as i32,
|
||||
desc.size.height as i32,
|
||||
);
|
||||
} else {
|
||||
gl.renderbuffer_storage(
|
||||
glow::RENDERBUFFER,
|
||||
format_desc.tex_internal,
|
||||
format_desc.internal,
|
||||
desc.size.width as i32,
|
||||
desc.size.height as i32,
|
||||
);
|
||||
@ -164,7 +417,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
gl.tex_storage_3d(
|
||||
target,
|
||||
desc.mip_level_count as i32,
|
||||
format_desc.tex_internal,
|
||||
format_desc.internal,
|
||||
desc.size.width as i32,
|
||||
desc.size.height as i32,
|
||||
desc.size.depth_or_array_layers as i32,
|
||||
@ -176,7 +429,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
gl.tex_storage_2d(
|
||||
target,
|
||||
desc.mip_level_count as i32,
|
||||
format_desc.tex_internal,
|
||||
format_desc.internal,
|
||||
desc.size.width as i32,
|
||||
desc.size.height as i32,
|
||||
);
|
||||
@ -189,7 +442,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
gl.tex_storage_3d(
|
||||
target,
|
||||
desc.mip_level_count as i32,
|
||||
format_desc.tex_internal,
|
||||
format_desc.internal,
|
||||
desc.size.width as i32,
|
||||
desc.size.height as i32,
|
||||
desc.size.depth_or_array_layers as i32,
|
||||
@ -391,37 +644,87 @@ impl crate::Device<super::Api> for super::Device {
|
||||
&self,
|
||||
desc: &crate::ShaderModuleDescriptor,
|
||||
shader: crate::ShaderInput,
|
||||
) -> Result<Resource, crate::ShaderError> {
|
||||
Ok(Resource)
|
||||
) -> Result<super::ShaderModule, crate::ShaderError> {
|
||||
Ok(super::ShaderModule {
|
||||
naga: match shader {
|
||||
crate::ShaderInput::SpirV(_) => panic!("Unable to pass-through SPIR-V"),
|
||||
crate::ShaderInput::Naga(naga) => naga,
|
||||
},
|
||||
})
|
||||
}
|
||||
unsafe fn destroy_shader_module(&self, module: Resource) {}
|
||||
unsafe fn destroy_shader_module(&self, _module: super::ShaderModule) {}
|
||||
|
||||
unsafe fn create_render_pipeline(
|
||||
&self,
|
||||
desc: &crate::RenderPipelineDescriptor<super::Api>,
|
||||
) -> Result<Resource, crate::PipelineError> {
|
||||
Ok(Resource)
|
||||
) -> Result<super::RenderPipeline, crate::PipelineError> {
|
||||
let shaders = iter::once((naga::ShaderStage::Vertex, &desc.vertex_stage)).chain(
|
||||
desc.fragment_stage
|
||||
.as_ref()
|
||||
.map(|fs| (naga::ShaderStage::Fragment, fs)),
|
||||
);
|
||||
let inner = self.create_pipeline(shaders, desc.layout)?;
|
||||
|
||||
let attributes = {
|
||||
let gl = &self.shared.context;
|
||||
let mut attributes = Vec::new();
|
||||
|
||||
for (index, vb_layout) in desc.vertex_buffers.iter().enumerate() {
|
||||
for vat in vb_layout.attributes.iter() {
|
||||
let format_desc = conv::describe_vertex_format(vat.format);
|
||||
attributes.push(super::AttributeDesc {
|
||||
location: vat.shader_location,
|
||||
offset: vat.offset as u32,
|
||||
buffer_index: index as u32,
|
||||
format_desc,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
attributes.into_boxed_slice()
|
||||
};
|
||||
|
||||
Ok(super::RenderPipeline {
|
||||
inner,
|
||||
primitive: desc.primitive.clone(),
|
||||
attributes,
|
||||
depth: desc.depth_stencil.clone(),
|
||||
})
|
||||
}
|
||||
unsafe fn destroy_render_pipeline(&self, pipeline: Resource) {}
|
||||
unsafe fn destroy_render_pipeline(&self, pipeline: super::RenderPipeline) {
|
||||
let gl = &self.shared.context;
|
||||
gl.delete_program(pipeline.inner.program);
|
||||
}
|
||||
|
||||
unsafe fn create_compute_pipeline(
|
||||
&self,
|
||||
desc: &crate::ComputePipelineDescriptor<super::Api>,
|
||||
) -> Result<Resource, crate::PipelineError> {
|
||||
Ok(Resource)
|
||||
) -> Result<super::ComputePipeline, crate::PipelineError> {
|
||||
let shaders = iter::once((naga::ShaderStage::Compute, &desc.stage));
|
||||
let inner = self.create_pipeline(shaders, desc.layout)?;
|
||||
|
||||
Ok(super::ComputePipeline { inner })
|
||||
}
|
||||
unsafe fn destroy_compute_pipeline(&self, pipeline: super::ComputePipeline) {
|
||||
let gl = &self.shared.context;
|
||||
gl.delete_program(pipeline.inner.program);
|
||||
}
|
||||
unsafe fn destroy_compute_pipeline(&self, pipeline: Resource) {}
|
||||
|
||||
unsafe fn create_query_set(
|
||||
&self,
|
||||
desc: &wgt::QuerySetDescriptor<crate::Label>,
|
||||
) -> DeviceResult<Resource> {
|
||||
) -> Result<Resource, crate::DeviceError> {
|
||||
Ok(Resource)
|
||||
}
|
||||
unsafe fn destroy_query_set(&self, set: Resource) {}
|
||||
unsafe fn create_fence(&self) -> DeviceResult<Resource> {
|
||||
unsafe fn create_fence(&self) -> Result<Resource, crate::DeviceError> {
|
||||
Ok(Resource)
|
||||
}
|
||||
unsafe fn destroy_fence(&self, fence: Resource) {}
|
||||
unsafe fn get_fence_value(&self, fence: &Resource) -> DeviceResult<crate::FenceValue> {
|
||||
unsafe fn get_fence_value(
|
||||
&self,
|
||||
fence: &Resource,
|
||||
) -> Result<crate::FenceValue, crate::DeviceError> {
|
||||
Ok(0)
|
||||
}
|
||||
unsafe fn wait(
|
||||
@ -429,7 +732,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
fence: &Resource,
|
||||
value: crate::FenceValue,
|
||||
timeout_ms: u32,
|
||||
) -> DeviceResult<bool> {
|
||||
) -> Result<bool, crate::DeviceError> {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
|
@ -587,7 +587,7 @@ impl crate::Surface<super::Api> for Surface {
|
||||
gl.bind_renderbuffer(glow::RENDERBUFFER, Some(renderbuffer));
|
||||
gl.renderbuffer_storage(
|
||||
glow::RENDERBUFFER,
|
||||
format_desc.tex_internal,
|
||||
format_desc.internal,
|
||||
config.extent.width as _,
|
||||
config.extent.height as _,
|
||||
);
|
||||
@ -606,7 +606,7 @@ impl crate::Surface<super::Api> for Surface {
|
||||
renderbuffer,
|
||||
framebuffer,
|
||||
extent: config.extent,
|
||||
format: format_desc.tex_internal,
|
||||
format: format_desc.internal,
|
||||
sample_type: wgt::TextureSampleType::Float { filterable: false },
|
||||
});
|
||||
|
||||
|
@ -21,7 +21,10 @@ pub struct Api;
|
||||
#[derive(Debug)]
|
||||
pub struct Resource;
|
||||
|
||||
type DeviceResult<T> = Result<T, crate::DeviceError>;
|
||||
//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_SAMPLER_SLOTS: usize = 16;
|
||||
const MAX_TEXTURE_SLOTS: usize = 16;
|
||||
|
||||
impl crate::Api for Api {
|
||||
type Instance = Instance;
|
||||
@ -44,9 +47,9 @@ impl crate::Api for Api {
|
||||
type BindGroupLayout = BindGroupLayout;
|
||||
type BindGroup = BindGroup;
|
||||
type PipelineLayout = PipelineLayout;
|
||||
type ShaderModule = Resource;
|
||||
type RenderPipeline = Resource;
|
||||
type ComputePipeline = Resource;
|
||||
type ShaderModule = ShaderModule;
|
||||
type RenderPipeline = RenderPipeline;
|
||||
type ComputePipeline = ComputePipeline;
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
@ -152,23 +155,22 @@ impl Sampled for SampledTextureBinding {
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum VertexAttribKind {
|
||||
Float, // glVertexAttribPointer
|
||||
Float, // glVertexAttribPointer
|
||||
Integer, // glVertexAttribIPointer
|
||||
Double, // glVertexAttribLPointer
|
||||
//Double, // glVertexAttribLPointer
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FormatDescription {
|
||||
tex_internal: u32,
|
||||
tex_external: u32,
|
||||
struct TextureFormatDesc {
|
||||
internal: u32,
|
||||
external: u32,
|
||||
data_type: u32,
|
||||
num_components: u8,
|
||||
va_kind: VertexAttribKind,
|
||||
}
|
||||
|
||||
struct AdapterShared {
|
||||
context: glow::Context,
|
||||
private_caps: PrivateCapability,
|
||||
shading_language_version: naga::back::glsl::Version,
|
||||
}
|
||||
|
||||
pub struct Adapter {
|
||||
@ -218,7 +220,7 @@ impl TextureInner {
|
||||
#[derive(Debug)]
|
||||
pub struct Texture {
|
||||
inner: TextureInner,
|
||||
format_desc: FormatDescription,
|
||||
format_desc: TextureFormatDesc,
|
||||
format_info: wgt::TextureFormatInfo,
|
||||
}
|
||||
|
||||
@ -258,6 +260,13 @@ pub struct PipelineLayout {
|
||||
group_infos: Box<[BindGroupLayoutInfo]>,
|
||||
}
|
||||
|
||||
impl PipelineLayout {
|
||||
fn get_slot(&self, br: &naga::ResourceBinding) -> u8 {
|
||||
let group_info = &self.group_infos[br.group as usize];
|
||||
group_info.binding_to_slot[br.binding as usize]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum BindingRegister {
|
||||
Textures,
|
||||
@ -287,6 +296,54 @@ pub struct BindGroup {
|
||||
contents: Box<[RawBinding]>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ShaderModule {
|
||||
naga: crate::NagaShader,
|
||||
}
|
||||
|
||||
struct VertexFormatDesc {
|
||||
element_count: i32,
|
||||
element_format: u32,
|
||||
attrib_kind: VertexAttribKind,
|
||||
}
|
||||
|
||||
struct AttributeDesc {
|
||||
location: u32,
|
||||
offset: u32,
|
||||
buffer_index: u32,
|
||||
format_desc: VertexFormatDesc,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct UniformDesc {
|
||||
location: glow::UniformLocation,
|
||||
offset: u32,
|
||||
utype: u32,
|
||||
}
|
||||
|
||||
/// For each texture in the pipeline layout, store the index of the only
|
||||
/// sampler (in this layout) that the texture is used with.
|
||||
type SamplerBindMap = [Option<u8>; MAX_TEXTURE_SLOTS];
|
||||
|
||||
struct PipelineInner {
|
||||
program: glow::Program,
|
||||
sampler_map: SamplerBindMap,
|
||||
uniforms: Box<[UniformDesc]>,
|
||||
}
|
||||
|
||||
pub struct RenderPipeline {
|
||||
inner: PipelineInner,
|
||||
//blend_targets: Vec<pso::ColorBlendDesc>,
|
||||
attributes: Box<[AttributeDesc]>,
|
||||
//vertex_buffers: Box<[wgt::VertexBufferLayout]>,
|
||||
primitive: wgt::PrimitiveState,
|
||||
depth: Option<wgt::DepthStencilState>,
|
||||
}
|
||||
|
||||
pub struct ComputePipeline {
|
||||
inner: PipelineInner,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct TextureCopyInfo {
|
||||
external_format: u32,
|
||||
@ -297,13 +354,13 @@ struct TextureCopyInfo {
|
||||
#[derive(Debug)]
|
||||
enum Command {
|
||||
Draw {
|
||||
primitive: u32,
|
||||
topology: u32,
|
||||
start_vertex: u32,
|
||||
vertex_count: u32,
|
||||
instance_count: u32,
|
||||
},
|
||||
DrawIndexed {
|
||||
primitive: u32,
|
||||
topology: u32,
|
||||
index_type: u32,
|
||||
index_count: u32,
|
||||
index_offset: wgt::BufferAddress,
|
||||
@ -311,12 +368,12 @@ enum Command {
|
||||
instance_count: u32,
|
||||
},
|
||||
DrawIndirect {
|
||||
primitive: u32,
|
||||
topology: u32,
|
||||
indirect_buf: glow::Buffer,
|
||||
indirect_offset: wgt::BufferAddress,
|
||||
},
|
||||
DrawIndexedIndirect {
|
||||
primitive: u32,
|
||||
topology: u32,
|
||||
index_type: u32,
|
||||
indirect_buf: glow::Buffer,
|
||||
indirect_offset: wgt::BufferAddress,
|
||||
@ -376,7 +433,7 @@ pub struct CommandBuffer {
|
||||
|
||||
#[derive(Default)]
|
||||
struct CommandState {
|
||||
primitive: u32,
|
||||
topology: u32,
|
||||
index_format: wgt::IndexFormat,
|
||||
index_offset: wgt::BufferAddress,
|
||||
}
|
||||
|
@ -20,16 +20,16 @@ impl super::Queue {
|
||||
let gl = &self.shared.context;
|
||||
match *command {
|
||||
C::Draw {
|
||||
primitive,
|
||||
topology,
|
||||
start_vertex,
|
||||
vertex_count,
|
||||
instance_count,
|
||||
} => {
|
||||
if instance_count == 1 {
|
||||
gl.draw_arrays(primitive, start_vertex as i32, vertex_count as i32);
|
||||
gl.draw_arrays(topology, start_vertex as i32, vertex_count as i32);
|
||||
} else {
|
||||
gl.draw_arrays_instanced(
|
||||
primitive,
|
||||
topology,
|
||||
start_vertex as i32,
|
||||
vertex_count as i32,
|
||||
instance_count as i32,
|
||||
@ -37,7 +37,7 @@ impl super::Queue {
|
||||
}
|
||||
}
|
||||
C::DrawIndexed {
|
||||
primitive,
|
||||
topology,
|
||||
index_type,
|
||||
index_count,
|
||||
index_offset,
|
||||
@ -45,27 +45,27 @@ impl super::Queue {
|
||||
instance_count,
|
||||
} => match (base_vertex, instance_count) {
|
||||
(0, 1) => gl.draw_elements(
|
||||
primitive,
|
||||
topology,
|
||||
index_count as i32,
|
||||
index_type,
|
||||
index_offset as i32,
|
||||
),
|
||||
(0, _) => gl.draw_elements_instanced(
|
||||
primitive,
|
||||
topology,
|
||||
index_count as i32,
|
||||
index_type,
|
||||
index_offset as i32,
|
||||
instance_count as i32,
|
||||
),
|
||||
(_, 1) => gl.draw_elements_base_vertex(
|
||||
primitive,
|
||||
topology,
|
||||
index_count as i32,
|
||||
index_type,
|
||||
index_offset as i32,
|
||||
base_vertex,
|
||||
),
|
||||
(_, _) => gl.draw_elements_instanced_base_vertex(
|
||||
primitive,
|
||||
topology,
|
||||
index_count as _,
|
||||
index_type,
|
||||
index_offset as i32,
|
||||
@ -74,16 +74,16 @@ impl super::Queue {
|
||||
),
|
||||
},
|
||||
C::DrawIndirect {
|
||||
primitive: _,
|
||||
topology: _,
|
||||
indirect_buf,
|
||||
indirect_offset: _,
|
||||
} => {
|
||||
gl.bind_buffer(glow::DRAW_INDIRECT_BUFFER, Some(indirect_buf));
|
||||
//TODO: https://github.com/grovesNL/glow/issues/172
|
||||
//gl.draw_arrays_indirect(primitive, indirect_offset);
|
||||
//gl.draw_arrays_indirect(topology, indirect_offset);
|
||||
}
|
||||
C::DrawIndexedIndirect {
|
||||
primitive: _,
|
||||
topology: _,
|
||||
index_type: _,
|
||||
indirect_buf,
|
||||
indirect_offset: _,
|
||||
|
@ -837,7 +837,6 @@ pub struct CommandEncoderDescriptor<'a, A: Api> {
|
||||
}
|
||||
|
||||
/// Naga shader module.
|
||||
#[derive(Debug)]
|
||||
pub struct NagaShader {
|
||||
/// Shader module IR.
|
||||
pub module: naga::Module,
|
||||
@ -845,6 +844,14 @@ pub struct NagaShader {
|
||||
pub info: naga::valid::ModuleInfo,
|
||||
}
|
||||
|
||||
// Custom implementation avoids the need to generate Debug impl code
|
||||
// for the whole Naga module and info.
|
||||
impl fmt::Debug for NagaShader {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "Naga shader")
|
||||
}
|
||||
}
|
||||
|
||||
/// Shader input.
|
||||
pub enum ShaderInput<'a> {
|
||||
Naga(NagaShader),
|
||||
|
@ -61,10 +61,10 @@ impl super::Device {
|
||||
},
|
||||
};
|
||||
|
||||
let module = &stage.module.raw.module;
|
||||
let module = &stage.module.naga.module;
|
||||
let (source, info) = naga::back::msl::write_string(
|
||||
module,
|
||||
&stage.module.raw.info,
|
||||
&stage.module.naga.info,
|
||||
&layout.naga_options,
|
||||
&pipeline_options,
|
||||
)
|
||||
@ -644,7 +644,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
shader: crate::ShaderInput,
|
||||
) -> Result<super::ShaderModule, crate::ShaderError> {
|
||||
match shader {
|
||||
crate::ShaderInput::Naga(raw) => Ok(super::ShaderModule { raw }),
|
||||
crate::ShaderInput::Naga(naga) => Ok(super::ShaderModule { naga }),
|
||||
crate::ShaderInput::SpirV(_) => {
|
||||
unreachable!("SPIRV_SHADER_PASSTHROUGH is not enabled for this backend")
|
||||
}
|
||||
|
@ -555,7 +555,7 @@ unsafe impl Sync for BindGroup {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ShaderModule {
|
||||
raw: crate::NagaShader,
|
||||
naga: crate::NagaShader,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
Loading…
Reference in New Issue
Block a user