hal/gles: describe format, adapter info

This commit is contained in:
Dzmitry Malyshau
2021-06-19 01:14:59 -04:00
committed by Dzmitry Malyshau
parent 41bc9d0625
commit d88bc440e6
6 changed files with 413 additions and 38 deletions

View File

@@ -0,0 +1,116 @@
use glow::HasContext;
use std::sync::Arc;
// https://webgl2fundamentals.org/webgl/lessons/webgl-data-textures.html
impl super::Adapter {
fn make_info(vendor_orig: String, renderer_orig: String) -> wgt::AdapterInfo {
let vendor = vendor_orig.to_lowercase();
let renderer = renderer_orig.to_lowercase();
// opengl has no way to discern device_type, so we can try to infer it from the renderer string
let strings_that_imply_integrated = [
" xpress", // space here is on purpose so we don't match express
"radeon hd 4200",
"radeon hd 4250",
"radeon hd 4290",
"radeon hd 4270",
"radeon hd 4225",
"radeon hd 3100",
"radeon hd 3200",
"radeon hd 3000",
"radeon hd 3300",
"radeon(tm) r4 graphics",
"radeon(tm) r5 graphics",
"radeon(tm) r6 graphics",
"radeon(tm) r7 graphics",
"radeon r7 graphics",
"nforce", // all nvidia nforce are integrated
"tegra", // all nvidia tegra are integrated
"shield", // all nvidia shield are integrated
"igp",
"mali",
"intel",
];
let strings_that_imply_cpu = ["mesa offscreen", "swiftshader", "lavapipe"];
//TODO: handle Intel Iris XE as discreet
let inferred_device_type = if vendor.contains("qualcomm")
|| vendor.contains("intel")
|| strings_that_imply_integrated
.iter()
.any(|&s| renderer.contains(s))
{
wgt::DeviceType::IntegratedGpu
} else if strings_that_imply_cpu.iter().any(|&s| renderer.contains(s)) {
wgt::DeviceType::Cpu
} else {
wgt::DeviceType::DiscreteGpu
};
// source: Sascha Willems at Vulkan
let vendor_id = if vendor.contains("amd") {
0x1002
} else if vendor.contains("imgtec") {
0x1010
} else if vendor.contains("nvidia") {
0x10DE
} else if vendor.contains("arm") {
0x13B5
} else if vendor.contains("qualcomm") {
0x5143
} else if vendor.contains("intel") {
0x8086
} else {
0
};
wgt::AdapterInfo {
name: renderer_orig,
vendor: vendor_id,
device: 0,
device_type: inferred_device_type,
backend: wgt::Backend::Gl,
}
}
pub(super) unsafe fn expose(gl: glow::Context) -> crate::ExposedAdapter<super::Api> {
let vendor = gl.get_parameter_string(glow::VENDOR);
let renderer = gl.get_parameter_string(glow::RENDERER);
let min_uniform_buffer_offset_alignment =
gl.get_parameter_i32(glow::UNIFORM_BUFFER_OFFSET_ALIGNMENT);
let min_storage_buffer_offset_alignment = if super::is_webgl() {
256
} else {
gl.get_parameter_i32(glow::SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT)
};
crate::ExposedAdapter {
adapter: super::Adapter {
shared: Arc::new(super::AdapterShared {
context: gl,
private_caps: super::PrivateCapabilities {},
}),
},
info: Self::make_info(vendor, renderer),
features: wgt::Features::empty(), //TODO
capabilities: crate::Capabilities {
limits: wgt::Limits::default(), //TODO
downlevel: wgt::DownlevelCapabilities::default(), //TODO
alignments: crate::Alignments {
buffer_copy_offset: wgt::BufferSize::new(4).unwrap(),
buffer_copy_pitch: wgt::BufferSize::new(4).unwrap(),
uniform_buffer_offset: wgt::BufferSize::new(
min_storage_buffer_offset_alignment as u64,
)
.unwrap(),
storage_buffer_offset: wgt::BufferSize::new(
min_uniform_buffer_offset_alignment as u64,
)
.unwrap(),
},
},
}
}
}

222
wgpu-hal/src/gles/conv.rs Normal file
View File

@@ -0,0 +1,222 @@
impl super::PrivateCapabilities {
pub(super) fn describe_texture_format(
&self,
format: wgt::TextureFormat,
) -> super::FormatDescription {
use super::VertexAttribKind as Vak;
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,
),
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::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
| Tf::Bc2RgbaUnorm
| Tf::Bc2RgbaUnormSrgb
| Tf::Bc3RgbaUnorm
| Tf::Bc3RgbaUnormSrgb
| Tf::Bc4RUnorm
| Tf::Bc4RSnorm
| Tf::Bc5RgUnorm
| Tf::Bc5RgSnorm
| Tf::Bc6hRgbSfloat
| Tf::Bc6hRgbUfloat
| Tf::Bc7RgbaUnorm
| Tf::Bc7RgbaUnormSrgb
| Tf::Etc2RgbUnorm
| Tf::Etc2RgbUnormSrgb
| Tf::Etc2RgbA1Unorm
| Tf::Etc2RgbA1UnormSrgb
| Tf::EacRUnorm
| Tf::EacRSnorm
| Tf::EtcRgUnorm
| Tf::EtcRgSnorm
| Tf::Astc4x4RgbaUnorm
| Tf::Astc4x4RgbaUnormSrgb
| Tf::Astc5x4RgbaUnorm
| Tf::Astc5x4RgbaUnormSrgb
| Tf::Astc5x5RgbaUnorm
| Tf::Astc5x5RgbaUnormSrgb
| Tf::Astc6x5RgbaUnorm
| Tf::Astc6x5RgbaUnormSrgb
| Tf::Astc6x6RgbaUnorm
| Tf::Astc6x6RgbaUnormSrgb
| Tf::Astc8x5RgbaUnorm
| Tf::Astc8x5RgbaUnormSrgb
| Tf::Astc8x6RgbaUnorm
| Tf::Astc8x6RgbaUnormSrgb
| Tf::Astc10x5RgbaUnorm
| Tf::Astc10x5RgbaUnormSrgb
| Tf::Astc10x6RgbaUnorm
| Tf::Astc10x6RgbaUnormSrgb
| Tf::Astc8x8RgbaUnorm
| Tf::Astc8x8RgbaUnormSrgb
| Tf::Astc10x8RgbaUnorm
| Tf::Astc10x8RgbaUnormSrgb
| Tf::Astc10x10RgbaUnorm
| Tf::Astc10x10RgbaUnormSrgb
| Tf::Astc12x10RgbaUnorm
| Tf::Astc12x10RgbaUnormSrgb
| Tf::Astc12x12RgbaUnorm
| Tf::Astc12x12RgbaUnormSrgb => unimplemented!(),
};
super::FormatDescription {
tex_internal,
tex_external,
data_type,
num_components,
va_kind,
}
}
}

View File

@@ -238,7 +238,7 @@ unsafe impl Sync for Instance {}
impl crate::Instance<super::Api> for Instance {
unsafe fn init(desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
let egl = match unsafe { egl::DynamicInstance::<egl::EGL1_4>::load_required() } {
let egl = match egl::DynamicInstance::<egl::EGL1_4>::load_required() {
Ok(egl) => Arc::new(egl),
Err(e) => {
log::warn!("Unable to open libEGL.so: {:?}", e);
@@ -447,10 +447,43 @@ impl crate::Instance<super::Api> for Instance {
swapchain: None,
})
}
unsafe fn destroy_surface(&self, surface: Surface) {}
unsafe fn destroy_surface(&self, surface: Surface) {
let inner = self.inner.lock();
inner
.egl
.destroy_surface(inner.display, surface.raw)
.unwrap();
if let Some(wl_window) = surface.wl_window {
let wl_egl_window_destroy: libloading::Symbol<WlEglWindowDestroyFun> = self
.wsi_library
.as_ref()
.expect("unsupported window")
.get(b"wl_egl_window_destroy")
.unwrap();
wl_egl_window_destroy(wl_window)
}
}
unsafe fn enumerate_adapters(&self) -> Vec<crate::ExposedAdapter<super::Api>> {
Vec::new()
let inner = self.inner.lock();
inner
.egl
.make_current(
inner.display,
inner.pbuffer,
inner.pbuffer,
Some(inner.context),
)
.unwrap();
let context = glow::Context::from_loader_function(|name| {
inner
.egl
.get_proc_address(name)
.map_or(ptr::null(), |p| p as *const _)
});
vec![super::Adapter::expose(context)]
}
}
@@ -482,7 +515,7 @@ unsafe impl Sync for Surface {}
impl crate::Surface<super::Api> for Surface {
unsafe fn configure(
&mut self,
device: &super::Context,
device: &super::Device,
config: &crate::SurfaceConfiguration,
) -> Result<(), crate::SurfaceError> {
self.unconfigure(device);
@@ -500,15 +533,16 @@ impl crate::Surface<super::Api> for Surface {
);
}
//let desc = conv::describe_format(config.format).unwrap();
let desc: super::FormatDescription = unimplemented!();
let gl: glow::Context = unimplemented!(); //&device.share.context;
let format_desc = device
.shared
.private_caps
.describe_texture_format(config.format);
let gl = &device.shared.context;
let renderbuffer = gl.create_renderbuffer().unwrap();
gl.bind_renderbuffer(glow::RENDERBUFFER, Some(renderbuffer));
gl.renderbuffer_storage(
glow::RENDERBUFFER,
desc.tex_internal,
format_desc.tex_internal,
config.extent.width as _,
config.extent.height as _,
);
@@ -527,20 +561,19 @@ impl crate::Surface<super::Api> for Surface {
renderbuffer,
framebuffer,
extent: config.extent,
format: desc.tex_internal,
format: format_desc.tex_internal,
sample_type: wgt::TextureSampleType::Float { filterable: false },
});
Ok(())
}
unsafe fn unconfigure(&mut self, device: &super::Context) {
/*
let gl = &device.share.context;
unsafe fn unconfigure(&mut self, device: &super::Device) {
let gl = &device.shared.context;
if let Some(sc) = self.swapchain.take() {
gl.delete_renderbuffer(sc.renderbuffer);
gl.delete_framebuffer(sc.framebuffer);
}*/
}
}
unsafe fn acquire_texture(
@@ -552,5 +585,5 @@ impl crate::Surface<super::Api> for Surface {
// native::SwapchainImage::new(sc.renderbuffer, sc.format, sc.extent, sc.channel);
Ok(None)
}
unsafe fn discard_texture(&mut self, texture: super::Resource) {}
unsafe fn discard_texture(&mut self, _texture: super::Resource) {}
}

View File

@@ -3,10 +3,13 @@
#[cfg(not(target_arch = "wasm32"))]
mod egl;
mod adapter;
mod conv;
#[cfg(not(target_arch = "wasm32"))]
use self::egl::{Instance, Surface};
use std::ops::Range;
use std::{ops::Range, sync::Arc};
#[derive(Clone)]
pub struct Api;
@@ -20,8 +23,8 @@ type DeviceResult<T> = Result<T, crate::DeviceError>;
impl crate::Api for Api {
type Instance = Instance;
type Surface = Surface;
type Adapter = Context;
type Device = Context;
type Adapter = Adapter;
type Device = Device;
type Queue = Context;
type CommandEncoder = Encoder;
@@ -43,6 +46,10 @@ impl crate::Api for Api {
type ComputePipeline = Resource;
}
const fn is_webgl() -> bool {
cfg!(target_arch = "wasm32")
}
type TextureFormat = u32;
#[derive(Debug, Clone, Copy)]
@@ -60,25 +67,22 @@ struct FormatDescription {
va_kind: VertexAttribKind,
}
impl FormatDescription {
fn new(
tex_internal: u32,
tex_external: u32,
data_type: u32,
num_components: u8,
va_kind: VertexAttribKind,
) -> Self {
FormatDescription {
tex_internal,
tex_external,
data_type,
num_components,
va_kind,
}
}
struct PrivateCapabilities {}
struct AdapterShared {
context: glow::Context,
private_caps: PrivateCapabilities,
}
impl crate::Adapter<Api> for Context {
pub struct Adapter {
shared: Arc<AdapterShared>,
}
pub struct Device {
shared: Arc<AdapterShared>,
}
impl crate::Adapter<Api> for Adapter {
unsafe fn open(&self, features: wgt::Features) -> DeviceResult<crate::OpenDevice<Api>> {
Err(crate::DeviceError::Lost)
}
@@ -110,7 +114,7 @@ impl crate::Queue<Api> for Context {
}
}
impl crate::Device<Api> for Context {
impl crate::Device<Api> for Device {
unsafe fn exit(self) {}
unsafe fn create_buffer(&self, desc: &crate::BufferDescriptor) -> DeviceResult<Resource> {
Ok(Resource)

View File

@@ -624,8 +624,8 @@ pub struct Alignments {
/// The alignment of the row pitch of the texture data stored in a buffer that is
/// used in a GPU copy operation.
pub buffer_copy_pitch: wgt::BufferSize,
pub storage_buffer_offset: wgt::BufferSize,
pub uniform_buffer_offset: wgt::BufferSize,
pub storage_buffer_offset: wgt::BufferSize,
}
#[derive(Clone, Debug)]

View File

@@ -905,8 +905,8 @@ impl super::PrivateCapabilities {
alignments: crate::Alignments {
buffer_copy_offset: buffer_alignment,
buffer_copy_pitch: wgt::BufferSize::new(4).unwrap(),
storage_buffer_offset: buffer_alignment,
uniform_buffer_offset: buffer_alignment,
storage_buffer_offset: buffer_alignment,
},
downlevel,
}