mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 16:24:24 +00:00
Enable Gles backend, add checks for downlevel flags
This commit is contained in:
parent
cf10138c64
commit
952173efde
@ -54,7 +54,7 @@ hal = { path = "../wgpu-hal", package = "wgpu-hal", features = ["metal"] }
|
||||
#Note: could also enable "vulkan" for Vulkan Portability
|
||||
|
||||
[target.'cfg(all(not(target_arch = "wasm32"), unix, not(target_os = "ios"), not(target_os = "macos")))'.dependencies]
|
||||
hal = { path = "../wgpu-hal", package = "wgpu-hal", features = ["vulkan"] }
|
||||
hal = { path = "../wgpu-hal", package = "wgpu-hal", features = ["vulkan", "gles"] }
|
||||
|
||||
[target.'cfg(all(not(target_arch = "wasm32"), windows))'.dependencies]
|
||||
hal = { path = "../wgpu-hal", package = "wgpu-hal", features = ["vulkan"] }
|
||||
|
@ -11,6 +11,6 @@ fn main() {
|
||||
metal: { all(not(wasm), apple) },
|
||||
dx12: { all(false, not(wasm), windows) },
|
||||
dx11: { all(false, not(wasm), windows) },
|
||||
gl: { all(false, any(wasm, unix_wo_apple)) },
|
||||
gl: { all(not(wasm), unix_wo_apple) },
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
device::{DeviceError, MissingFeatures, SHADER_STAGE_COUNT},
|
||||
device::{DeviceError, MissingDownlevelFlags, MissingFeatures, SHADER_STAGE_COUNT},
|
||||
hub::Resource,
|
||||
id::{BindGroupLayoutId, BufferId, DeviceId, SamplerId, TextureViewId, Valid},
|
||||
memory_init_tracker::MemoryInitTrackerAction,
|
||||
@ -28,6 +28,8 @@ pub enum BindGroupLayoutEntryError {
|
||||
ArrayUnsupported,
|
||||
#[error(transparent)]
|
||||
MissingFeatures(#[from] MissingFeatures),
|
||||
#[error(transparent)]
|
||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
|
@ -39,7 +39,10 @@ use crate::{
|
||||
StateChange,
|
||||
},
|
||||
conv,
|
||||
device::{AttachmentData, Device, DeviceError, RenderPassContext, SHADER_STAGE_COUNT},
|
||||
device::{
|
||||
AttachmentData, Device, DeviceError, MissingDownlevelFlags, RenderPassContext,
|
||||
SHADER_STAGE_COUNT,
|
||||
},
|
||||
hub::{GlobalIdentityHandlerFactory, HalApi, Hub, Resource, Storage, Token},
|
||||
id,
|
||||
memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction},
|
||||
@ -403,6 +406,10 @@ impl RenderBundleEncoder {
|
||||
indirect: true,
|
||||
pipeline: state.pipeline.last_state,
|
||||
};
|
||||
device
|
||||
.require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
let buffer = state
|
||||
.trackers
|
||||
.buffers
|
||||
@ -439,6 +446,10 @@ impl RenderBundleEncoder {
|
||||
indirect: true,
|
||||
pipeline: state.pipeline.last_state,
|
||||
};
|
||||
device
|
||||
.require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
let buffer = state
|
||||
.trackers
|
||||
.buffers
|
||||
@ -1104,6 +1115,8 @@ pub(super) enum RenderBundleErrorInner {
|
||||
ResourceUsageConflict(#[from] UsageConflict),
|
||||
#[error(transparent)]
|
||||
Draw(#[from] DrawError),
|
||||
#[error(transparent)]
|
||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||
}
|
||||
|
||||
impl<T> From<T> for RenderBundleErrorInner
|
||||
|
@ -5,6 +5,7 @@ use crate::{
|
||||
CommandEncoderError, CommandEncoderStatus, MapPassErr, PassErrorScope, QueryUseError,
|
||||
StateChange,
|
||||
},
|
||||
device::MissingDownlevelFlags,
|
||||
hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token},
|
||||
id,
|
||||
memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction},
|
||||
@ -157,6 +158,8 @@ pub enum ComputePassErrorInner {
|
||||
PushConstants(#[from] PushConstantUploadError),
|
||||
#[error(transparent)]
|
||||
QueryUse(#[from] QueryUseError),
|
||||
#[error(transparent)]
|
||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||
}
|
||||
|
||||
/// Error encountered when performing a compute pass.
|
||||
@ -257,6 +260,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let hub = A::hub(self);
|
||||
let mut token = Token::root();
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
|
||||
let (mut cmd_buf_guard, mut token) = hub.command_buffers.write(&mut token);
|
||||
let cmd_buf =
|
||||
CommandBuffer::get_encoder_mut(&mut *cmd_buf_guard, encoder_id).map_pass_err(scope)?;
|
||||
@ -264,6 +269,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
cmd_buf.status = CommandEncoderStatus::Error;
|
||||
let raw = cmd_buf.encoder.open();
|
||||
|
||||
let device = &device_guard[cmd_buf.device_id.value];
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut list) = cmd_buf.commands {
|
||||
list.push(crate::device::trace::Command::RunComputePass {
|
||||
@ -500,6 +507,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
state.is_ready().map_pass_err(scope)?;
|
||||
|
||||
device
|
||||
.require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
let indirect_buffer = state
|
||||
.trackers
|
||||
.buffers
|
||||
|
@ -6,7 +6,10 @@ use crate::{
|
||||
PassErrorScope, QueryResetMap, QueryUseError, RenderCommand, RenderCommandError,
|
||||
StateChange,
|
||||
},
|
||||
device::{AttachmentData, RenderPassCompatibilityError, RenderPassContext},
|
||||
device::{
|
||||
AttachmentData, MissingDownlevelFlags, MissingFeatures, RenderPassCompatibilityError,
|
||||
RenderPassContext,
|
||||
},
|
||||
hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token},
|
||||
id,
|
||||
memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction},
|
||||
@ -419,8 +422,10 @@ pub enum RenderPassErrorInner {
|
||||
SampleCountMismatch { actual: u32, expected: u32 },
|
||||
#[error("setting `values_offset` to be `None` is only for internal use in render bundles")]
|
||||
InvalidValuesOffset,
|
||||
#[error("required device features not enabled: {0:?}")]
|
||||
MissingDeviceFeatures(wgt::Features),
|
||||
#[error(transparent)]
|
||||
MissingFeatures(#[from] MissingFeatures),
|
||||
#[error(transparent)]
|
||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||
#[error("indirect draw uses bytes {offset}..{end_offset} {} which overruns indirect buffer of size {buffer_size}", count.map_or_else(String::new, |v| format!("(using count {})", v)))]
|
||||
IndirectBufferOverrun {
|
||||
count: Option<NonZeroU32>,
|
||||
@ -483,17 +488,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn check_device_features(
|
||||
actual: wgt::Features,
|
||||
expected: wgt::Features,
|
||||
) -> Result<(), RenderPassErrorInner> {
|
||||
if !actual.contains(expected) {
|
||||
Err(RenderPassErrorInner::MissingDeviceFeatures(expected))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
struct RenderAttachment<'a> {
|
||||
texture_id: &'a Stored<id::TextureId>,
|
||||
selector: &'a TextureSelector,
|
||||
@ -1402,12 +1396,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
};
|
||||
|
||||
if count.is_some() {
|
||||
check_device_features(
|
||||
device.features,
|
||||
wgt::Features::MULTI_DRAW_INDIRECT,
|
||||
)
|
||||
.map_pass_err(scope)?;
|
||||
device
|
||||
.require_features(wgt::Features::MULTI_DRAW_INDIRECT)
|
||||
.map_pass_err(scope)?;
|
||||
}
|
||||
device
|
||||
.require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
let indirect_buffer = info
|
||||
.trackers
|
||||
@ -1476,11 +1471,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
true => mem::size_of::<wgt::DrawIndexedIndirectArgs>(),
|
||||
} as u64;
|
||||
|
||||
check_device_features(
|
||||
device.features,
|
||||
wgt::Features::MULTI_DRAW_INDIRECT_COUNT,
|
||||
)
|
||||
.map_pass_err(scope)?;
|
||||
device
|
||||
.require_features(wgt::Features::MULTI_DRAW_INDIRECT_COUNT)
|
||||
.map_pass_err(scope)?;
|
||||
device
|
||||
.require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
let indirect_buffer = info
|
||||
.trackers
|
||||
|
@ -254,6 +254,27 @@ pub enum CreateDeviceError {
|
||||
OutOfMemory,
|
||||
}
|
||||
|
||||
impl<A: hal::Api> Device<A> {
|
||||
pub(crate) fn require_features(&self, feature: wgt::Features) -> Result<(), MissingFeatures> {
|
||||
if self.features.contains(feature) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(MissingFeatures(feature))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn require_downlevel_flags(
|
||||
&self,
|
||||
flags: wgt::DownlevelFlags,
|
||||
) -> Result<(), MissingDownlevelFlags> {
|
||||
if self.downlevel.flags.contains(flags) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(MissingDownlevelFlags(flags))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Device<A> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn new(
|
||||
@ -312,25 +333,6 @@ impl<A: HalApi> Device<A> {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn require_features(&self, feature: wgt::Features) -> Result<(), MissingFeatures> {
|
||||
if self.features.contains(feature) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(MissingFeatures(feature))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn require_downlevel_flags(
|
||||
&self,
|
||||
flags: wgt::DownlevelFlags,
|
||||
) -> Result<(), MissingDownlevelFlags> {
|
||||
if self.downlevel.flags.contains(flags) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(MissingDownlevelFlags(flags))
|
||||
}
|
||||
}
|
||||
|
||||
fn lock_life_internal<'this, 'token: 'this>(
|
||||
tracker: &'this Mutex<life::LifetimeTracker<A>>,
|
||||
_token: &mut Token<'token, Self>,
|
||||
@ -1038,6 +1040,14 @@ impl<A: HalApi> Device<A> {
|
||||
if is_writable_storage && entry.visibility.contains(wgt::ShaderStage::VERTEX) {
|
||||
required_features |= wgt::Features::VERTEX_WRITABLE_STORAGE;
|
||||
}
|
||||
if is_writable_storage && entry.visibility.contains(wgt::ShaderStage::FRAGMENT) {
|
||||
self.require_downlevel_flags(wgt::DownlevelFlags::FRAGMENT_WRITABLE_STORAGE)
|
||||
.map_err(binding_model::BindGroupLayoutEntryError::MissingDownlevelFlags)
|
||||
.map_err(|error| binding_model::CreateBindGroupLayoutError::Entry {
|
||||
binding: entry.binding,
|
||||
error,
|
||||
})?;
|
||||
}
|
||||
|
||||
self.require_features(required_features)
|
||||
.map_err(binding_model::BindGroupLayoutEntryError::MissingFeatures)
|
||||
@ -2423,7 +2433,7 @@ pub struct MissingFeatures(pub wgt::Features);
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[error(
|
||||
"Downlevel flags {0:?} are required but not supported on the device. {}",
|
||||
"Downlevel flags {0:?} are required but not supported on the device.\n{}",
|
||||
DOWNLEVEL_ERROR_WARNING_MESSAGE
|
||||
)]
|
||||
pub struct MissingDownlevelFlags(pub wgt::DownlevelFlags);
|
||||
|
@ -854,7 +854,7 @@ impl HalApi for hal::api::Dx11 {
|
||||
surface.dx11.as_mut().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
#[cfg(gl)]
|
||||
impl HalApi for hal::api::Gles {
|
||||
const VARIANT: Backend = Backend::Gl;
|
||||
@ -864,7 +864,7 @@ impl HalApi for hal::api::Gles {
|
||||
fn get_surface_mut(surface: &mut Surface) -> &mut Self::Surface {
|
||||
surface.gl.as_mut().unwrap()
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn _test_send_sync(global: &Global<IdentityManagerFactory>) {
|
||||
|
@ -31,35 +31,35 @@ pub struct Instance {
|
||||
|
||||
impl Instance {
|
||||
pub fn new(name: &str, backends: BackendBit) -> Self {
|
||||
let mut flags = hal::InstanceFlag::empty();
|
||||
if cfg!(debug_assertions) {
|
||||
flags |= hal::InstanceFlag::VALIDATION;
|
||||
flags |= hal::InstanceFlag::DEBUG;
|
||||
}
|
||||
let hal_desc = hal::InstanceDescriptor {
|
||||
name: "wgpu",
|
||||
flags,
|
||||
};
|
||||
|
||||
let map = |backend: Backend| unsafe {
|
||||
if backends.contains(backend.into()) {
|
||||
hal::Instance::init(&hal_desc).ok()
|
||||
fn init<A: HalApi>(mask: BackendBit) -> Option<A::Instance> {
|
||||
if mask.contains(A::VARIANT.into()) {
|
||||
let mut flags = hal::InstanceFlag::empty();
|
||||
if cfg!(debug_assertions) {
|
||||
flags |= hal::InstanceFlag::VALIDATION;
|
||||
flags |= hal::InstanceFlag::DEBUG;
|
||||
}
|
||||
let hal_desc = hal::InstanceDescriptor {
|
||||
name: "wgpu",
|
||||
flags,
|
||||
};
|
||||
unsafe { hal::Instance::init(&hal_desc).ok() }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
#[cfg(vulkan)]
|
||||
vulkan: map(Backend::Vulkan),
|
||||
vulkan: init::<hal::api::Vulkan>(backends),
|
||||
#[cfg(metal)]
|
||||
metal: map(Backend::Metal),
|
||||
metal: init::<hal::api::Metal>(backends),
|
||||
#[cfg(dx12)]
|
||||
dx12: map(Backend::Dx12),
|
||||
dx12: init(Backend::Dx12, backends),
|
||||
#[cfg(dx11)]
|
||||
dx11: map(Backend::Dx11),
|
||||
dx11: init(Backend::Dx11, backends),
|
||||
#[cfg(gl)]
|
||||
gl: map(Backend::Gl),
|
||||
gl: init::<hal::api::Gles>(backends),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,14 +207,12 @@ macro_rules! gfx_select {
|
||||
wgt::Backend::Vulkan => $global.$method::<$crate::api::Vulkan>( $($param),* ),
|
||||
#[cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))]
|
||||
wgt::Backend::Metal => $global.$method::<$crate::api::Metal>( $($param),* ),
|
||||
/*
|
||||
#[cfg(all(not(target_arch = "wasm32"), windows))]
|
||||
wgt::Backend::Dx12 => $global.$method::<$crate::backend::Dx12>( $($param),* ),
|
||||
#[cfg(all(not(target_arch = "wasm32"), windows))]
|
||||
wgt::Backend::Dx11 => $global.$method::<$crate::backend::Dx11>( $($param),* ),
|
||||
#[cfg(any(target_arch = "wasm32", all(unix, not(any(target_os = "ios", target_os = "macos")))))]
|
||||
wgt::Backend::Gl => $global.$method::<$crate::backend::Gl>( $($param),+ ),
|
||||
*/
|
||||
//#[cfg(all(not(target_arch = "wasm32"), windows))]
|
||||
//wgt::Backend::Dx12 => $global.$method::<$crate::api::Dx12>( $($param),* ),
|
||||
//#[cfg(all(not(target_arch = "wasm32"), windows))]
|
||||
//wgt::Backend::Dx11 => $global.$method::<$crate::api::Dx11>( $($param),* ),
|
||||
#[cfg(all(not(target_arch = "wasm32"), unix, not(any(target_os = "ios", target_os = "macos"))))]
|
||||
wgt::Backend::Gl => $global.$method::<$crate::api::Gles>( $($param),+ ),
|
||||
other => panic!("Unexpected backend {:?}", other),
|
||||
|
||||
}
|
||||
|
@ -245,10 +245,6 @@ impl super::Adapter {
|
||||
};
|
||||
|
||||
let mut private_caps = super::PrivateCapability::empty();
|
||||
private_caps.set(
|
||||
super::PrivateCapability::EXPLICIT_LAYOUTS_IN_SHADER,
|
||||
ver >= (3, 1),
|
||||
);
|
||||
private_caps.set(super::PrivateCapability::MEMORY_BARRIERS, ver >= (3, 1));
|
||||
|
||||
Some(crate::ExposedAdapter {
|
||||
|
@ -36,8 +36,13 @@ impl CompilationContext<'_> {
|
||||
let slot = self.layout.get_slot(br);
|
||||
|
||||
let name = reflection_info.uniforms[&handle].clone();
|
||||
log::debug!("Rebind buffer: {:?} -> {}, register={:?}, slot={}",
|
||||
var.name.as_ref(), &name, register, slot);
|
||||
log::debug!(
|
||||
"Rebind buffer: {:?} -> {}, register={:?}, slot={}",
|
||||
var.name.as_ref(),
|
||||
&name,
|
||||
register,
|
||||
slot
|
||||
);
|
||||
self.name_binding_map.insert(name, (register, slot));
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,8 @@ extern "C" {
|
||||
}
|
||||
|
||||
type EglLabel = *const raw::c_void;
|
||||
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
type EGLDEBUGPROCKHR = Option<
|
||||
unsafe extern "system" fn(
|
||||
error: egl::Enum,
|
||||
@ -203,7 +205,7 @@ fn gl_debug_message_callback(source: u32, gltype: u32, id: u32, severity: u32, m
|
||||
message
|
||||
);
|
||||
|
||||
if log_severity == log::Level::Error {
|
||||
if log_severity == log::Level::Error && false {
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
@ -53,10 +53,8 @@ bitflags::bitflags! {
|
||||
/// Flags that affect internal code paths but do not
|
||||
/// change the exposed feature set.
|
||||
struct PrivateCapability: u32 {
|
||||
/// Support explicit layouts in shader.
|
||||
const EXPLICIT_LAYOUTS_IN_SHADER = 0x0001;
|
||||
/// Support memory barriers.
|
||||
const MEMORY_BARRIERS = 0x0002;
|
||||
const MEMORY_BARRIERS = 0x0001;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -558,11 +558,6 @@ impl crate::Device<super::Api> for super::Device {
|
||||
{
|
||||
let mut flags = gpu_alloc::UsageFlags::HOST_ACCESS;
|
||||
//TODO: find a way to use `crate::MemoryFlag::PREFER_COHERENT`
|
||||
flags.set(
|
||||
gpu_alloc::UsageFlags::COHERENT,
|
||||
desc.memory_flags
|
||||
.contains(crate::MemoryFlag::PREFER_COHERENT),
|
||||
);
|
||||
flags.set(
|
||||
gpu_alloc::UsageFlags::DOWNLOAD,
|
||||
desc.usage.contains(crate::BufferUse::MAP_READ),
|
||||
|
Loading…
Reference in New Issue
Block a user