LibWeb/WebGL: Implement compressedTex(Sub)Image2D

This commit is contained in:
Luke Wilde 2025-01-28 17:26:23 +00:00 committed by Andreas Kling
parent f1b81b1ae2
commit 484008d440
Notes: github-actions[bot] 2025-02-09 00:01:50 +00:00
4 changed files with 64 additions and 4 deletions

View file

@ -39,10 +39,10 @@ interface mixin WebGL2RenderingContextOverloads {
undefined texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, unsigned long long srcOffset);
[FIXME] undefined compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLintptr offset);
[FIXME] undefined compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, [AllowShared] ArrayBufferView srcData, optional unsigned long long srcOffset = 0, optional GLuint srcLengthOverride = 0);
undefined compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, [AllowShared] ArrayBufferView srcData, optional unsigned long long srcOffset = 0, optional GLuint srcLengthOverride = 0);
[FIXME] undefined compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLintptr offset);
[FIXME] undefined compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,GLsizei width, GLsizei height, GLenum format, [AllowShared] ArrayBufferView srcData, optional unsigned long long srcOffset = 0, optional GLuint srcLengthOverride = 0);
undefined compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, [AllowShared] ArrayBufferView srcData, optional unsigned long long srcOffset = 0, optional GLuint srcLengthOverride = 0);
undefined uniform1fv(WebGLUniformLocation? location, Float32List v, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0);
undefined uniform2fv(WebGLUniformLocation? location, Float32List v, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0);

View file

@ -14,6 +14,7 @@ class WebGLRenderingContextBase {
public:
virtual GC::Cell const* gc_cell() const = 0;
virtual void visit_edges(JS::Cell::Visitor&) = 0;
virtual OpenGLContext& context() = 0;
};
}

View file

@ -19,8 +19,8 @@ interface mixin WebGLRenderingContextOverloads {
undefined bufferData(GLenum target, BufferSource? data, GLenum usage);
undefined bufferSubData(GLenum target, GLintptr offset, BufferSource data);
[FIXME] undefined compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, [AllowShared] ArrayBufferView data);
[FIXME] undefined compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, [AllowShared] ArrayBufferView data);
undefined compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, [AllowShared] ArrayBufferView data);
undefined compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, [AllowShared] ArrayBufferView data);
undefined readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels);

View file

@ -1199,6 +1199,54 @@ public:
continue;
}
if (webgl_version == 2 && function.name == "compressedTexImage2D"sv && function.overload_index == 0) {
function_impl_generator.append(R"~~~(
u8 const* pixels_ptr = src_data->viewed_array_buffer()->buffer().data();
size_t count = src_data->byte_length();
auto src_data_element_size = src_data->element_size();
if ((src_offset * src_data_element_size) + src_length_override > count) {
set_error(GL_INVALID_VALUE);
return;
}
pixels_ptr += src_data->byte_offset();
pixels_ptr += src_offset * src_data_element_size;
if (src_length_override == 0) {
count -= src_offset;
} else {
count = src_length_override;
}
glCompressedTexImage2D(target, level, internalformat, width, height, border, count, pixels_ptr);
)~~~");
continue;
}
if (webgl_version == 2 && function.name == "compressedTexSubImage2D"sv && function.overload_index == 0) {
function_impl_generator.append(R"~~~(
u8 const* pixels_ptr = src_data->viewed_array_buffer()->buffer().data();
size_t count = src_data->byte_length();
auto src_data_element_size = src_data->element_size();
if ((src_offset * src_data_element_size) + src_length_override > count) {
set_error(GL_INVALID_VALUE);
return;
}
pixels_ptr += src_data->byte_offset();
pixels_ptr += src_offset * src_data_element_size;
if (src_length_override == 0) {
count -= src_offset;
} else {
count = src_length_override;
}
glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, count, pixels_ptr);
)~~~");
continue;
}
if (function.name == "getShaderParameter"sv) {
generate_webgl_object_handle_unwrap(function_impl_generator, "shader"sv, "JS::js_null()"sv);
function_impl_generator.append(R"~~~(
@ -1998,6 +2046,17 @@ public:
} else {
VERIFY_NOT_REACHED();
}
)~~~");
gl_call_arguments.append(ByteString::formatted("byte_size"));
gl_call_arguments.append(ByteString::formatted("ptr"));
continue;
}
if (parameter.type->name() == "ArrayBufferView"sv) {
function_impl_generator.set("buffer_source_name", parameter_name);
function_impl_generator.append(R"~~~(
void const* ptr = @buffer_source_name@->viewed_array_buffer()->buffer().data() + @buffer_source_name@->byte_offset();
size_t byte_size = @buffer_source_name@->byte_length();
)~~~");
gl_call_arguments.append(ByteString::formatted("byte_size"));
gl_call_arguments.append(ByteString::formatted("ptr"));