diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index 307a2865c3..857945377b 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -327,6 +327,7 @@ impl crate::CommandEncoder for super::CommandEncoder { dst: dst_raw, dst_target, copy, + dst_is_cubemap: dst.is_cubemap, }) } } diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 3defc44c0b..0688abb056 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -528,7 +528,7 @@ impl crate::Device for super::Device { depth: 1, }; - let inner = if render_usage.contains(desc.usage) + let (inner, is_cubemap) = if render_usage.contains(desc.usage) && desc.dimension == wgt::TextureDimension::D2 && desc.size.depth_or_array_layers == 1 { @@ -559,10 +559,10 @@ impl crate::Device for super::Device { } gl.bind_renderbuffer(glow::RENDERBUFFER, None); - super::TextureInner::Renderbuffer { raw } + (super::TextureInner::Renderbuffer { raw }, false) } else { let raw = gl.create_texture().unwrap(); - let (target, is_3d) = match desc.dimension { + let (target, is_3d, is_cubemap) = match desc.dimension { wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => { if desc.size.depth_or_array_layers > 1 { //HACK: detect a cube map @@ -575,17 +575,17 @@ impl crate::Device for super::Device { None }; match cube_count { - None => (glow::TEXTURE_2D_ARRAY, true), - Some(1) => (glow::TEXTURE_CUBE_MAP, false), - Some(_) => (glow::TEXTURE_CUBE_MAP_ARRAY, true), + None => (glow::TEXTURE_2D_ARRAY, true, false), + Some(1) => (glow::TEXTURE_CUBE_MAP, false, true), + Some(_) => (glow::TEXTURE_CUBE_MAP_ARRAY, true, true), } } else { - (glow::TEXTURE_2D, false) + (glow::TEXTURE_2D, false, false) } } wgt::TextureDimension::D3 => { copy_size.depth = desc.size.depth_or_array_layers; - (glow::TEXTURE_3D, true) + (glow::TEXTURE_3D, true, false) } }; @@ -639,7 +639,7 @@ impl crate::Device for super::Device { } gl.bind_texture(target, None); - super::TextureInner::Texture { raw, target } + (super::TextureInner::Texture { raw, target }, is_cubemap) }; Ok(super::Texture { @@ -653,6 +653,7 @@ impl crate::Device for super::Device { format: desc.format, format_desc, copy_size, + is_cubemap, }) } unsafe fn destroy_texture(&self, texture: super::Texture) { diff --git a/wgpu-hal/src/gles/egl.rs b/wgpu-hal/src/gles/egl.rs index 06167ec841..ceec43fc7c 100644 --- a/wgpu-hal/src/gles/egl.rs +++ b/wgpu-hal/src/gles/egl.rs @@ -1210,6 +1210,7 @@ impl crate::Surface for Surface { height: sc.extent.height, depth: 1, }, + is_cubemap: false, }; Ok(Some(crate::AcquiredSurfaceTexture { texture, diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 338cbca774..11f7aee704 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -262,6 +262,7 @@ pub struct Texture { #[allow(unused)] format_desc: TextureFormatDesc, copy_size: crate::CopyExtent, + is_cubemap: bool, } impl Texture { @@ -281,6 +282,7 @@ impl Texture { height: 0, depth: 0, }, + is_cubemap: false, } } } @@ -616,6 +618,7 @@ enum Command { dst: glow::Texture, dst_target: BindTarget, copy: crate::TextureCopy, + dst_is_cubemap: bool, }, CopyBufferToTexture { src: Buffer, diff --git a/wgpu-hal/src/gles/queue.rs b/wgpu-hal/src/gles/queue.rs index 2af9e72f21..bc06c081f8 100644 --- a/wgpu-hal/src/gles/queue.rs +++ b/wgpu-hal/src/gles/queue.rs @@ -308,10 +308,10 @@ impl super::Queue { src_target, dst, dst_target, + dst_is_cubemap, ref copy, } => { //TODO: handle 3D copies - //TODO: handle cubemap copies gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(self.copy_fbo)); if is_layered_target(src_target) { //TODO: handle GLES without framebuffer_texture_3d @@ -333,7 +333,18 @@ impl super::Queue { } gl.bind_texture(dst_target, Some(dst)); - if is_layered_target(dst_target) { + if dst_is_cubemap { + gl.copy_tex_sub_image_2d( + CUBEMAP_FACES[copy.dst_base.array_layer as usize], + copy.dst_base.mip_level as i32, + copy.dst_base.origin.x as i32, + copy.dst_base.origin.y as i32, + copy.src_base.origin.x as i32, + copy.src_base.origin.y as i32, + copy.size.width as i32, + copy.size.height as i32, + ); + } else if is_layered_target(dst_target) { gl.copy_tex_sub_image_3d( dst_target, copy.dst_base.mip_level as i32, diff --git a/wgpu-hal/src/gles/web.rs b/wgpu-hal/src/gles/web.rs index 1c0ee6a9db..db4c32b382 100644 --- a/wgpu-hal/src/gles/web.rs +++ b/wgpu-hal/src/gles/web.rs @@ -270,6 +270,7 @@ impl crate::Surface for Surface { height: sc.extent.height, depth: 1, }, + is_cubemap: false, }; Ok(Some(crate::AcquiredSurfaceTexture { texture,