WebGL2: support TexImage3D (#37718)

Add TexImage3D method to WebGL2RenderingContext

Testing: conformance2 should pass. Also it should get
http://webglsamples.org/WebGL2Samples/#texture_2d_array and
http://webglsamples.org/WebGL2Samples/#texture_3d running.
Fixes: #26511

Now Servo can run texture_2d_array and texture_3d samples!

![圖片](https://github.com/user-attachments/assets/41b87563-08b8-4db3-b503-12f3a61dbed7)

![圖片](https://github.com/user-attachments/assets/3c62a4de-35ea-488d-b2e5-00e3aed52090)

And it can now run three.js too!

![圖片](https://github.com/user-attachments/assets/d880aa92-a154-4895-aa06-b7919d1fc869)

---------

Signed-off-by: Wu Yu Wei <yuweiwu@pm.me>
This commit is contained in:
Ngo Iok Ui (Wu Yu Wei) 2025-07-09 23:22:03 +09:00 committed by GitHub
parent 4499fdeb2b
commit 34c31ee418
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 1341 additions and 980 deletions

View file

@ -143,7 +143,7 @@ pub(crate) unsafe fn uniform_typed<T>(
/// Set of bitflags for texture unpacking (texImage2d, etc...)
#[derive(Clone, Copy, JSTraceable, MallocSizeOf)]
struct TextureUnpacking(u8);
pub(crate) struct TextureUnpacking(u8);
bitflags! {
impl TextureUnpacking: u8 {
@ -327,6 +327,10 @@ impl WebGLRenderingContext {
self.texture_unpacking_alignment.get()
}
pub(crate) fn bound_draw_framebuffer(&self) -> Option<DomRoot<WebGLFramebuffer>> {
self.bound_draw_framebuffer.get()
}
pub(crate) fn current_vao(&self) -> DomRoot<WebGLVertexArrayObjectOES> {
self.current_vao.or_init(|| {
DomRoot::from_ref(
@ -1680,6 +1684,8 @@ impl WebGLRenderingContext {
constants::BOOL |
constants::INT |
constants::SAMPLER_2D |
WebGL2RenderingContextConstants::SAMPLER_2D_ARRAY |
WebGL2RenderingContextConstants::SAMPLER_3D |
constants::SAMPLER_CUBE => {},
_ => return Err(InvalidOperation),
}
@ -1687,7 +1693,10 @@ impl WebGLRenderingContext {
let val = self.uniform_vec_section_int(val, src_offset, src_length, 1, location)?;
match location.type_() {
constants::SAMPLER_2D | constants::SAMPLER_CUBE => {
constants::SAMPLER_2D |
constants::SAMPLER_CUBE |
WebGL2RenderingContextConstants::SAMPLER_2D_ARRAY |
WebGL2RenderingContextConstants::SAMPLER_3D => {
for &v in val
.iter()
.take(cmp::min(location.size().unwrap_or(1) as usize, val.len()))
@ -2149,6 +2158,30 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
texture.to_jsval(*cx, retval);
return;
},
WebGL2RenderingContextConstants::TEXTURE_BINDING_2D_ARRAY => unsafe {
let texture = self
.textures
.active_texture_slot(
WebGL2RenderingContextConstants::TEXTURE_2D_ARRAY,
self.webgl_version(),
)
.unwrap()
.get();
texture.to_jsval(*cx, retval);
return;
},
WebGL2RenderingContextConstants::TEXTURE_BINDING_3D => unsafe {
let texture = self
.textures
.active_texture_slot(
WebGL2RenderingContextConstants::TEXTURE_3D,
self.webgl_version(),
)
.unwrap()
.get();
texture.to_jsval(*cx, retval);
return;
},
constants::TEXTURE_BINDING_CUBE_MAP => unsafe {
let texture = self
.textures
@ -4036,7 +4069,10 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
self.with_location(location, |location| {
match location.type_() {
constants::BOOL | constants::INT => {},
constants::SAMPLER_2D | constants::SAMPLER_CUBE => {
constants::SAMPLER_2D |
WebGL2RenderingContextConstants::SAMPLER_3D |
WebGL2RenderingContextConstants::SAMPLER_2D_ARRAY |
constants::SAMPLER_CUBE => {
if val < 0 || val as u32 >= self.limits.max_combined_texture_image_units {
return Err(InvalidValue);
}
@ -4237,7 +4273,11 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
constants::BOOL_VEC4 => unsafe {
uniform_get(triple, WebGLCommand::GetUniformBool4).to_jsval(*cx, rval);
},
constants::INT | constants::SAMPLER_2D | constants::SAMPLER_CUBE => {
constants::INT |
constants::SAMPLER_2D |
constants::SAMPLER_CUBE |
WebGL2RenderingContextConstants::SAMPLER_2D_ARRAY |
WebGL2RenderingContextConstants::SAMPLER_3D => {
rval.set(Int32Value(uniform_get(triple, WebGLCommand::GetUniformInt)))
},
constants::INT_VEC2 => unsafe {
@ -5122,6 +5162,22 @@ impl TexPixels {
pub(crate) fn size(&self) -> Size2D<u32> {
self.size
}
pub(crate) fn pixel_format(&self) -> Option<PixelFormat> {
self.pixel_format
}
pub(crate) fn alpha_treatment(&self) -> Option<AlphaTreatment> {
self.alpha_treatment
}
pub(crate) fn y_axis_treatment(&self) -> YAxisTreatment {
self.y_axis_treatment
}
pub(crate) fn into_shared_memory(self) -> IpcSharedMemory {
self.data
}
}
pub(crate) enum TexSource {