diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 9c8a4f3180..1abb27fd4d 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -4,6 +4,7 @@ // ``` unittests:* webgpu:api,operation,buffers,createBindGroup:buffer_binding_resource:* +webgpu:api,operation,buffers,map:mapAsync,read:* webgpu:api,operation,command_buffer,basic:* webgpu:api,operation,command_buffer,copyBufferToBuffer:* fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth24plus" diff --git a/tests/tests/wgpu-gpu/cloneable_types.rs b/tests/tests/wgpu-gpu/cloneable_types.rs index fd578f6cc9..ffae024ff3 100644 --- a/tests/tests/wgpu-gpu/cloneable_types.rs +++ b/tests/tests/wgpu-gpu/cloneable_types.rs @@ -28,9 +28,6 @@ fn cloneable_buffers(ctx: TestingContext) { buffer.unmap(); - // This is actually a bug, we should not need to call submit to make the buffer contents visible. - ctx.queue.submit([]); - let cloned_buffer = buffer.clone(); let cloned_buffer_contents = buffer_contents.clone(); diff --git a/wgpu-core/src/conv.rs b/wgpu-core/src/conv.rs index 0003c991d2..3c1a1bf4f5 100644 --- a/wgpu-core/src/conv.rs +++ b/wgpu-core/src/conv.rs @@ -26,7 +26,7 @@ pub fn is_valid_external_image_copy_dst_texture_format(format: wgt::TextureForma } } -pub fn map_buffer_usage(usage: wgt::BufferUsages) -> wgt::BufferUses { +pub fn map_buffer_usage(usage: wgt::BufferUsages, mapped_at_creation: bool) -> wgt::BufferUses { let mut u = wgt::BufferUses::empty(); u.set( wgt::BufferUses::MAP_READ, @@ -34,7 +34,8 @@ pub fn map_buffer_usage(usage: wgt::BufferUsages) -> wgt::BufferUses { ); u.set( wgt::BufferUses::MAP_WRITE, - usage.contains(wgt::BufferUsages::MAP_WRITE), + usage.contains(wgt::BufferUsages::MAP_WRITE) + || (usage.contains(wgt::BufferUsages::MAP_READ) && mapped_at_creation), ); u.set( wgt::BufferUses::COPY_SRC, diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 94834746c5..bb171b6b93 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -900,7 +900,7 @@ impl Device { } } - let mut usage = conv::map_buffer_usage(desc.usage); + let mut usage = conv::map_buffer_usage(desc.usage, desc.mapped_at_creation); if desc.usage.contains(wgt::BufferUsages::INDIRECT) { self.require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)?; @@ -990,7 +990,10 @@ impl Device { let buffer_use = if !desc.mapped_at_creation { wgt::BufferUses::empty() - } else if desc.usage.contains(wgt::BufferUsages::MAP_WRITE) { + } else if desc + .usage + .intersects(wgt::BufferUsages::MAP_WRITE | wgt::BufferUsages::MAP_READ) + { // buffer is mappable, so we are just doing that at start let map_size = buffer.size; let mapping = if map_size == 0 { diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index e85809e604..a508de976f 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -526,7 +526,10 @@ impl crate::Device for super::Device { .private_caps .contains(PrivateCapabilities::BUFFER_ALLOCATION); - if emulate_map && desc.usage.intersects(wgt::BufferUses::MAP_WRITE) { + if emulate_map + && (desc.usage.intersects(wgt::BufferUses::MAP_WRITE) + && !desc.usage.intersects(wgt::BufferUses::MAP_READ)) + { return Ok(super::Buffer { raw: None, target, @@ -692,12 +695,21 @@ impl crate::Device for super::Device { } unsafe fn unmap_buffer(&self, buffer: &super::Buffer) { if let Some(raw) = buffer.raw { - if buffer.data.is_none() { - let gl = &self.shared.context.lock(); - unsafe { gl.bind_buffer(buffer.target, Some(raw)) }; - unsafe { gl.unmap_buffer(buffer.target) }; - unsafe { gl.bind_buffer(buffer.target, None) }; - *lock(&buffer.offset_of_current_mapping) = 0; + match &buffer.data { + None => { + let gl = &self.shared.context.lock(); + unsafe { gl.bind_buffer(buffer.target, Some(raw)) }; + unsafe { gl.unmap_buffer(buffer.target) }; + unsafe { gl.bind_buffer(buffer.target, None) }; + *lock(&buffer.offset_of_current_mapping) = 0; + } + Some(data) => { + let gl = &self.shared.context.lock(); + let data = lock(&*data); + unsafe { gl.bind_buffer(buffer.target, Some(raw)) }; + unsafe { gl.buffer_sub_data_u8_slice(buffer.target, 0, &data) }; + unsafe { gl.bind_buffer(buffer.target, None) }; + } } } }