mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
hal/egl: add coherence preference, hook up EGL_KHR_debug message callbacks
This commit is contained in:
committed by
Dzmitry Malyshau
parent
c7356e124e
commit
8fd6b36e6c
@@ -239,7 +239,7 @@ impl<A: hal::Api> Example<A> {
|
||||
label: Some("stage"),
|
||||
size: texture_data.len() as wgt::BufferAddress,
|
||||
usage: hal::BufferUse::MAP_WRITE | hal::BufferUse::COPY_SRC,
|
||||
memory_flags: hal::MemoryFlag::TRANSIENT,
|
||||
memory_flags: hal::MemoryFlag::TRANSIENT | hal::MemoryFlag::PREFER_COHERENT,
|
||||
};
|
||||
let staging_buffer = unsafe { device.create_buffer(&staging_buffer_desc).unwrap() };
|
||||
unsafe {
|
||||
@@ -342,7 +342,7 @@ impl<A: hal::Api> Example<A> {
|
||||
label: Some("global"),
|
||||
size: mem::size_of::<Globals>() as wgt::BufferAddress,
|
||||
usage: hal::BufferUse::MAP_WRITE | hal::BufferUse::UNIFORM,
|
||||
memory_flags: hal::MemoryFlag::empty(),
|
||||
memory_flags: hal::MemoryFlag::PREFER_COHERENT,
|
||||
};
|
||||
let global_buffer = unsafe {
|
||||
let buffer = device.create_buffer(&global_buffer_desc).unwrap();
|
||||
@@ -363,7 +363,7 @@ impl<A: hal::Api> Example<A> {
|
||||
label: Some("local"),
|
||||
size: (MAX_BUNNIES as wgt::BufferAddress) * wgt::BIND_BUFFER_ALIGNMENT,
|
||||
usage: hal::BufferUse::MAP_WRITE | hal::BufferUse::UNIFORM,
|
||||
memory_flags: hal::MemoryFlag::empty(),
|
||||
memory_flags: hal::MemoryFlag::PREFER_COHERENT,
|
||||
};
|
||||
let local_buffer = unsafe { device.create_buffer(&local_buffer_desc).unwrap() };
|
||||
|
||||
@@ -474,6 +474,10 @@ impl<A: hal::Api> Example<A> {
|
||||
})
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
self.bunnies.is_empty()
|
||||
}
|
||||
|
||||
fn exit(mut self) {
|
||||
unsafe {
|
||||
{
|
||||
@@ -732,11 +736,12 @@ fn main() {
|
||||
}
|
||||
},
|
||||
winit::event::Event::RedrawRequested(_) => {
|
||||
let ex = example.as_mut().unwrap();
|
||||
{
|
||||
accum_time += last_frame_inst.elapsed().as_secs_f32();
|
||||
last_frame_inst = Instant::now();
|
||||
frame_count += 1;
|
||||
if frame_count == 100 {
|
||||
if frame_count == 100 && !ex.is_empty() {
|
||||
println!(
|
||||
"Avg frame time {}ms",
|
||||
accum_time * 1000.0 / frame_count as f32
|
||||
@@ -745,7 +750,7 @@ fn main() {
|
||||
frame_count = 0;
|
||||
}
|
||||
}
|
||||
example.as_mut().unwrap().render();
|
||||
ex.render();
|
||||
}
|
||||
winit::event::Event::LoopDestroyed => {
|
||||
example.take().unwrap().exit();
|
||||
|
||||
@@ -167,13 +167,13 @@ impl super::Adapter {
|
||||
|
||||
let ver = Self::parse_version(&version).ok()?;
|
||||
let extensions = gl.supported_extensions();
|
||||
log::info!("Extensions: {:?}", extensions);
|
||||
log::debug!("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;
|
||||
let (sl_major, sl_minor) = Self::parse_version(&sl_version).ok()?;
|
||||
let value = sl_major as u16 * 100 + sl_minor as u16 * 10;
|
||||
naga::back::glsl::Version::Embedded(value)
|
||||
};
|
||||
|
||||
|
||||
@@ -403,23 +403,22 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
// issue the clears
|
||||
for (i, cat) in desc.color_attachments.iter().enumerate() {
|
||||
if !cat.ops.contains(crate::AttachmentOp::LOAD) {
|
||||
let draw_buffer = glow::DRAW_BUFFER0 + i as u32;
|
||||
let c = &cat.clear_value;
|
||||
self.cmd_buffer
|
||||
.commands
|
||||
.push(match cat.target.view.sample_type {
|
||||
wgt::TextureSampleType::Float { .. } => C::ClearColorF(
|
||||
draw_buffer,
|
||||
[c.r as f32, c.g as f32, c.r as f32, c.a as f32],
|
||||
i as u32,
|
||||
[c.r as f32, c.g as f32, c.b as f32, c.a as f32],
|
||||
),
|
||||
wgt::TextureSampleType::Depth => unimplemented!(),
|
||||
wgt::TextureSampleType::Uint => C::ClearColorU(
|
||||
draw_buffer,
|
||||
[c.r as u32, c.g as u32, c.r as u32, c.a as u32],
|
||||
i as u32,
|
||||
[c.r as u32, c.g as u32, c.b as u32, c.a as u32],
|
||||
),
|
||||
wgt::TextureSampleType::Sint => C::ClearColorI(
|
||||
draw_buffer,
|
||||
[c.r as i32, c.g as i32, c.r as i32, c.a as i32],
|
||||
i as u32,
|
||||
[c.r as i32, c.g as i32, c.b as i32, c.a as i32],
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -275,19 +275,19 @@ impl crate::Device<super::Api> for super::Device {
|
||||
} else {
|
||||
glow::ARRAY_BUFFER
|
||||
};
|
||||
let map_coherent = false;
|
||||
let map_flags = glow::MAP_PERSISTENT_BIT
|
||||
| if map_coherent {
|
||||
glow::MAP_COHERENT_BIT
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let mut storage_flags = 0;
|
||||
|
||||
let mut 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) {
|
||||
storage_flags |= map_flags | glow::MAP_READ_BIT;
|
||||
map_flags |= glow::MAP_READ_BIT;
|
||||
}
|
||||
if desc.usage.contains(crate::BufferUse::MAP_WRITE) {
|
||||
storage_flags |= map_flags | glow::MAP_WRITE_BIT;
|
||||
map_flags |= glow::MAP_WRITE_BIT;
|
||||
}
|
||||
|
||||
let raw = gl.create_buffer().unwrap();
|
||||
@@ -296,7 +296,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
.size
|
||||
.try_into()
|
||||
.map_err(|_| crate::DeviceError::OutOfMemory)?;
|
||||
gl.buffer_storage(target, raw_size, None, storage_flags);
|
||||
gl.buffer_storage(target, raw_size, None, map_flags);
|
||||
gl.bind_buffer(target, None);
|
||||
|
||||
Ok(super::Buffer {
|
||||
@@ -513,11 +513,63 @@ impl crate::Device<super::Api> for super::Device {
|
||||
&self,
|
||||
desc: &crate::SamplerDescriptor,
|
||||
) -> Result<super::Sampler, crate::DeviceError> {
|
||||
use super::Sampled;
|
||||
let gl = &self.shared.context;
|
||||
|
||||
let raw = gl.create_sampler().unwrap();
|
||||
super::SamplerBinding(raw).configure_sampling(gl, desc);
|
||||
|
||||
let (min, mag) =
|
||||
conv::map_filter_modes(desc.min_filter, desc.mag_filter, desc.mipmap_filter);
|
||||
|
||||
gl.sampler_parameter_i32(raw, glow::TEXTURE_MIN_FILTER, min as i32);
|
||||
gl.sampler_parameter_i32(raw, glow::TEXTURE_MAG_FILTER, mag as i32);
|
||||
|
||||
gl.sampler_parameter_i32(
|
||||
raw,
|
||||
glow::TEXTURE_WRAP_S,
|
||||
conv::map_address_mode(desc.address_modes[0]) as i32,
|
||||
);
|
||||
gl.sampler_parameter_i32(
|
||||
raw,
|
||||
glow::TEXTURE_WRAP_T,
|
||||
conv::map_address_mode(desc.address_modes[1]) as i32,
|
||||
);
|
||||
gl.sampler_parameter_i32(
|
||||
raw,
|
||||
glow::TEXTURE_WRAP_R,
|
||||
conv::map_address_mode(desc.address_modes[2]) as i32,
|
||||
);
|
||||
|
||||
if let Some(border_color) = desc.border_color {
|
||||
let mut border = match border_color {
|
||||
wgt::SamplerBorderColor::TransparentBlack => [0.0; 4],
|
||||
wgt::SamplerBorderColor::OpaqueBlack => [0.0, 0.0, 0.0, 1.0],
|
||||
wgt::SamplerBorderColor::OpaqueWhite => [1.0; 4],
|
||||
};
|
||||
gl.sampler_parameter_f32_slice(raw, glow::TEXTURE_BORDER_COLOR, &mut border);
|
||||
}
|
||||
|
||||
if let Some(ref range) = desc.lod_clamp {
|
||||
gl.sampler_parameter_f32(raw, glow::TEXTURE_MIN_LOD, range.start);
|
||||
gl.sampler_parameter_f32(raw, glow::TEXTURE_MAX_LOD, range.end);
|
||||
}
|
||||
|
||||
//TODO: `desc.anisotropy_clamp` depends on the downlevel flag
|
||||
// gl.sampler_parameter_f32(rawow::TEXTURE_MAX_ANISOTROPY, aniso as f32);
|
||||
|
||||
//set_param_float(glow::TEXTURE_LOD_BIAS, info.lod_bias.0);
|
||||
|
||||
if let Some(compare) = desc.compare {
|
||||
gl.sampler_parameter_i32(
|
||||
raw,
|
||||
glow::TEXTURE_COMPARE_MODE,
|
||||
glow::COMPARE_REF_TO_TEXTURE as i32,
|
||||
);
|
||||
gl.sampler_parameter_i32(
|
||||
raw,
|
||||
glow::TEXTURE_COMPARE_FUNC,
|
||||
conv::map_compare_func(compare) as i32,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(super::Sampler { raw })
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use glow::HasContext;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use std::{os::raw, ptr, sync::Arc};
|
||||
use std::{ffi::CStr, os::raw, ptr, sync::Arc};
|
||||
|
||||
const EGL_PLATFORM_WAYLAND_KHR: u32 = 0x31D8;
|
||||
const EGL_PLATFORM_X11_KHR: u32 = 0x31D5;
|
||||
@@ -41,6 +41,56 @@ extern "C" {
|
||||
) -> i32;
|
||||
}
|
||||
|
||||
type EglLabel = *const raw::c_void;
|
||||
type EGLDEBUGPROCKHR = Option<
|
||||
unsafe extern "system" fn(
|
||||
error: egl::Enum,
|
||||
command: *const raw::c_char,
|
||||
message_type: u32,
|
||||
thread_label: EglLabel,
|
||||
object_label: EglLabel,
|
||||
message: *const raw::c_char,
|
||||
),
|
||||
>;
|
||||
|
||||
const EGL_DEBUG_MSG_CRITICAL_KHR: u32 = 0x33B9;
|
||||
const EGL_DEBUG_MSG_ERROR_KHR: u32 = 0x33BA;
|
||||
const EGL_DEBUG_MSG_WARN_KHR: u32 = 0x33BB;
|
||||
const EGL_DEBUG_MSG_INFO_KHR: u32 = 0x33BC;
|
||||
|
||||
type EglDebugMessageControlFun =
|
||||
unsafe extern "system" fn(proc: EGLDEBUGPROCKHR, attrib_list: *const egl::Attrib) -> raw::c_int;
|
||||
|
||||
unsafe extern "system" fn egl_debug_proc(
|
||||
error: egl::Enum,
|
||||
command_raw: *const raw::c_char,
|
||||
message_type: u32,
|
||||
_thread_label: EglLabel,
|
||||
_object_label: EglLabel,
|
||||
message_raw: *const raw::c_char,
|
||||
) {
|
||||
let log_severity = match message_type {
|
||||
EGL_DEBUG_MSG_CRITICAL_KHR | EGL_DEBUG_MSG_ERROR_KHR => log::Level::Error,
|
||||
EGL_DEBUG_MSG_WARN_KHR => log::Level::Warn,
|
||||
EGL_DEBUG_MSG_INFO_KHR => log::Level::Info,
|
||||
_ => log::Level::Debug,
|
||||
};
|
||||
let command = CStr::from_ptr(command_raw).to_string_lossy();
|
||||
let message = if message_raw.is_null() {
|
||||
"".into()
|
||||
} else {
|
||||
CStr::from_ptr(message_raw).to_string_lossy()
|
||||
};
|
||||
|
||||
log::log!(
|
||||
log_severity,
|
||||
"EGL '{}' code 0x{:x}: {}",
|
||||
command,
|
||||
error,
|
||||
message,
|
||||
);
|
||||
}
|
||||
|
||||
fn open_x_display() -> Option<(ptr::NonNull<raw::c_void>, libloading::Library)> {
|
||||
log::info!("Loading X11 library to get the current display");
|
||||
unsafe {
|
||||
@@ -112,7 +162,7 @@ fn choose_config(
|
||||
Err(crate::InstanceError)
|
||||
}
|
||||
|
||||
fn debug_message_callback(source: u32, gltype: u32, id: u32, severity: u32, message: &str) {
|
||||
fn gl_debug_message_callback(source: u32, gltype: u32, id: u32, severity: u32, message: &str) {
|
||||
let source_str = match source {
|
||||
glow::DEBUG_SOURCE_API => "API",
|
||||
glow::DEBUG_SOURCE_WINDOW_SYSTEM => "Window System",
|
||||
@@ -146,12 +196,16 @@ fn debug_message_callback(source: u32, gltype: u32, id: u32, severity: u32, mess
|
||||
|
||||
log::log!(
|
||||
log_severity,
|
||||
"[{}/{}] ID {} : {}",
|
||||
"GLES: [{}/{}] ID {} : {}",
|
||||
source_str,
|
||||
type_str,
|
||||
id,
|
||||
message
|
||||
);
|
||||
|
||||
if log_severity == log::Level::Error {
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -181,11 +235,10 @@ impl Inner {
|
||||
.query_string(Some(display), egl::EXTENSIONS)
|
||||
.unwrap()
|
||||
.to_string_lossy();
|
||||
log::info!(
|
||||
"Display vendor {:?}, version {:?}, extensions: {:?}",
|
||||
vendor,
|
||||
version,
|
||||
display_extensions
|
||||
log::info!("Display vendor {:?}, version {:?}", vendor, version,);
|
||||
log::debug!(
|
||||
"Display extensions: {:#?}",
|
||||
display_extensions.split_whitespace().collect::<Vec<_>>()
|
||||
);
|
||||
|
||||
if log::max_level() >= log::LevelFilter::Trace {
|
||||
@@ -211,7 +264,7 @@ impl Inner {
|
||||
egl::CONTEXT_CLIENT_VERSION,
|
||||
3, // Request GLES 3.0 or higher
|
||||
];
|
||||
if flags.contains(crate::InstanceFlag::VALIDATION)
|
||||
if flags.contains(crate::InstanceFlag::DEBUG)
|
||||
&& wsi_library.is_none()
|
||||
&& !cfg!(target_os = "android")
|
||||
{
|
||||
@@ -294,7 +347,10 @@ impl crate::Instance<super::Api> for Instance {
|
||||
Ok(ext) => ext.to_string_lossy().into_owned(),
|
||||
Err(_) => String::new(),
|
||||
};
|
||||
log::info!("Client extensions: {:?}", client_ext_str);
|
||||
log::debug!(
|
||||
"Client extensions: {:#?}",
|
||||
client_ext_str.split_whitespace().collect::<Vec<_>>()
|
||||
);
|
||||
|
||||
let mut wsi_library = None;
|
||||
|
||||
@@ -335,6 +391,26 @@ impl crate::Instance<super::Api> for Instance {
|
||||
egl.get_display(egl::DEFAULT_DISPLAY).unwrap()
|
||||
};
|
||||
|
||||
if desc.flags.contains(crate::InstanceFlag::VALIDATION)
|
||||
&& client_ext_str.contains(&"EGL_KHR_debug")
|
||||
{
|
||||
log::info!("Enabling EGL debug output");
|
||||
let function: EglDebugMessageControlFun =
|
||||
std::mem::transmute(egl.get_proc_address("eglDebugMessageControlKHR").unwrap());
|
||||
let attributes = [
|
||||
EGL_DEBUG_MSG_CRITICAL_KHR as egl::Attrib,
|
||||
1,
|
||||
EGL_DEBUG_MSG_ERROR_KHR as egl::Attrib,
|
||||
1,
|
||||
EGL_DEBUG_MSG_WARN_KHR as egl::Attrib,
|
||||
1,
|
||||
EGL_DEBUG_MSG_INFO_KHR as egl::Attrib,
|
||||
1,
|
||||
egl::ATTRIB_NONE,
|
||||
];
|
||||
(function)(Some(egl_debug_proc), attributes.as_ptr());
|
||||
}
|
||||
|
||||
let inner = Inner::create(desc.flags, egl, display, wsi_library.as_ref())?;
|
||||
|
||||
Ok(Instance {
|
||||
@@ -356,6 +432,7 @@ impl crate::Instance<super::Api> for Instance {
|
||||
#[cfg(not(any(target_os = "android", target_os = "macos")))]
|
||||
let (mut temp_xlib_handle, mut temp_xcb_handle);
|
||||
|
||||
#[allow(trivial_casts)]
|
||||
let native_window_ptr = match has_handle.raw_window_handle() {
|
||||
#[cfg(not(any(target_os = "android", target_os = "macos")))]
|
||||
Rwh::Xlib(handle) => {
|
||||
@@ -396,9 +473,13 @@ impl crate::Instance<super::Api> for Instance {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let new_inner =
|
||||
Inner::create(inner.egl.clone(), display, self.wsi_library.as_ref())
|
||||
.map_err(|_| w::InitError::UnsupportedWindowHandle)?;
|
||||
let new_inner = Inner::create(
|
||||
self.flags,
|
||||
inner.egl.clone(),
|
||||
display,
|
||||
self.wsi_library.as_ref(),
|
||||
)
|
||||
.map_err(|_| crate::InstanceError)?;
|
||||
|
||||
let old_inner = std::mem::replace(inner.deref_mut(), new_inner);
|
||||
inner.wl_display = Some(handle.display);
|
||||
@@ -526,9 +607,10 @@ impl crate::Instance<super::Api> for Instance {
|
||||
.map_or(ptr::null(), |p| p as *const _)
|
||||
});
|
||||
|
||||
if self.flags.contains(crate::InstanceFlag::DEBUG) && gl.supports_debug() {
|
||||
if self.flags.contains(crate::InstanceFlag::VALIDATION) && gl.supports_debug() {
|
||||
log::info!("Enabling GLES debug output");
|
||||
gl.enable(glow::DEBUG_OUTPUT);
|
||||
gl.debug_message_callback(debug_message_callback);
|
||||
gl.debug_message_callback(gl_debug_message_callback);
|
||||
}
|
||||
|
||||
super::Adapter::expose(gl).into_iter().collect()
|
||||
@@ -581,7 +663,6 @@ 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,
|
||||
|
||||
@@ -62,95 +62,6 @@ bitflags::bitflags! {
|
||||
|
||||
type BindTarget = u32;
|
||||
|
||||
trait Sampled {
|
||||
unsafe fn set_param_float(&self, gl: &glow::Context, key: u32, value: f32);
|
||||
// see https://github.com/grovesNL/glow/issues/170
|
||||
unsafe fn set_param_float_vec(&self, gl: &glow::Context, key: u32, values: &mut [f32]);
|
||||
unsafe fn set_param_int(&self, gl: &glow::Context, key: u32, value: i32);
|
||||
|
||||
unsafe fn configure_sampling(&self, gl: &glow::Context, desc: &crate::SamplerDescriptor) {
|
||||
let (min, mag) =
|
||||
conv::map_filter_modes(desc.min_filter, desc.mag_filter, desc.mipmap_filter);
|
||||
|
||||
self.set_param_int(gl, glow::TEXTURE_MIN_FILTER, min as i32);
|
||||
self.set_param_int(gl, glow::TEXTURE_MAG_FILTER, mag as i32);
|
||||
|
||||
self.set_param_int(
|
||||
gl,
|
||||
glow::TEXTURE_WRAP_S,
|
||||
conv::map_address_mode(desc.address_modes[0]) as i32,
|
||||
);
|
||||
self.set_param_int(
|
||||
gl,
|
||||
glow::TEXTURE_WRAP_T,
|
||||
conv::map_address_mode(desc.address_modes[1]) as i32,
|
||||
);
|
||||
self.set_param_int(
|
||||
gl,
|
||||
glow::TEXTURE_WRAP_R,
|
||||
conv::map_address_mode(desc.address_modes[2]) as i32,
|
||||
);
|
||||
|
||||
if let Some(border_color) = desc.border_color {
|
||||
let mut border = match border_color {
|
||||
wgt::SamplerBorderColor::TransparentBlack => [0.0; 4],
|
||||
wgt::SamplerBorderColor::OpaqueBlack => [0.0, 0.0, 0.0, 1.0],
|
||||
wgt::SamplerBorderColor::OpaqueWhite => [1.0; 4],
|
||||
};
|
||||
self.set_param_float_vec(gl, glow::TEXTURE_BORDER_COLOR, &mut border);
|
||||
}
|
||||
|
||||
if let Some(ref range) = desc.lod_clamp {
|
||||
self.set_param_float(gl, glow::TEXTURE_MIN_LOD, range.start);
|
||||
self.set_param_float(gl, glow::TEXTURE_MAX_LOD, range.end);
|
||||
}
|
||||
|
||||
//TODO: `desc.anisotropy_clamp` depends on the downlevel flag
|
||||
// self.set_param_float(glow::TEXTURE_MAX_ANISOTROPY, aniso as f32);
|
||||
|
||||
//set_param_float(glow::TEXTURE_LOD_BIAS, info.lod_bias.0);
|
||||
|
||||
if let Some(compare) = desc.compare {
|
||||
self.set_param_int(
|
||||
gl,
|
||||
glow::TEXTURE_COMPARE_MODE,
|
||||
glow::COMPARE_REF_TO_TEXTURE as i32,
|
||||
);
|
||||
self.set_param_int(
|
||||
gl,
|
||||
glow::TEXTURE_COMPARE_FUNC,
|
||||
conv::map_compare_func(compare) as i32,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SamplerBinding(glow::Sampler);
|
||||
impl Sampled for SamplerBinding {
|
||||
unsafe fn set_param_float(&self, gl: &glow::Context, key: u32, value: f32) {
|
||||
gl.sampler_parameter_f32(self.0, key, value);
|
||||
}
|
||||
unsafe fn set_param_float_vec(&self, gl: &glow::Context, key: u32, values: &mut [f32]) {
|
||||
gl.sampler_parameter_f32_slice(self.0, key, values);
|
||||
}
|
||||
unsafe fn set_param_int(&self, gl: &glow::Context, key: u32, value: i32) {
|
||||
gl.sampler_parameter_i32(self.0, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
struct SampledTextureBinding(BindTarget);
|
||||
impl Sampled for SampledTextureBinding {
|
||||
unsafe fn set_param_float(&self, gl: &glow::Context, key: u32, value: f32) {
|
||||
gl.tex_parameter_f32(self.0, key, value);
|
||||
}
|
||||
unsafe fn set_param_float_vec(&self, gl: &glow::Context, key: u32, values: &mut [f32]) {
|
||||
gl.tex_parameter_f32_slice(self.0, key, values);
|
||||
}
|
||||
unsafe fn set_param_int(&self, gl: &glow::Context, key: u32, value: i32) {
|
||||
gl.tex_parameter_i32(self.0, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum VertexAttribKind {
|
||||
Float, // glVertexAttribPointer
|
||||
|
||||
@@ -20,6 +20,7 @@ impl super::Queue {
|
||||
unsafe fn reset_state(&self) {
|
||||
let gl = &self.shared.context;
|
||||
gl.use_program(None);
|
||||
gl.bind_framebuffer(glow::FRAMEBUFFER, None);
|
||||
gl.polygon_offset(0.0, 0.0);
|
||||
gl.disable(glow::DEPTH_TEST);
|
||||
gl.disable(glow::STENCIL_TEST);
|
||||
|
||||
@@ -554,6 +554,7 @@ impl From<wgt::TextureFormat> for FormatAspect {
|
||||
bitflags!(
|
||||
pub struct MemoryFlag: u32 {
|
||||
const TRANSIENT = 1;
|
||||
const PREFER_COHERENT = 2;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -140,6 +140,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
|
||||
let mut options = mtl::MTLResourceOptions::empty();
|
||||
options |= if map_read || map_write {
|
||||
// `crate::MemoryFlag::PREFER_COHERENT` is ignored here
|
||||
mtl::MTLResourceOptions::StorageModeShared
|
||||
} else {
|
||||
mtl::MTLResourceOptions::StorageModePrivate
|
||||
|
||||
@@ -557,6 +557,11 @@ impl crate::Device<super::Api> for super::Device {
|
||||
.intersects(crate::BufferUse::MAP_READ | crate::BufferUse::MAP_WRITE)
|
||||
{
|
||||
let mut flags = gpu_alloc::UsageFlags::HOST_ACCESS;
|
||||
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),
|
||||
|
||||
Reference in New Issue
Block a user