LibGL: Implement glGetTexImage

The plumbing was already there in LibGPU, so all that was left was to
implement the API :^)
This commit is contained in:
Jelle Raaijmakers 2022-09-01 13:30:24 +02:00 committed by Andreas Kling
parent 4f69022c32
commit 8ab410a536
6 changed files with 46 additions and 0 deletions

View file

@ -739,6 +739,7 @@ GLAPI void glTexGenfv(GLenum coord, GLenum pname, GLfloat const* params);
GLAPI void glTexGeni(GLenum coord, GLenum pname, GLint param);
GLAPI void glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
GLAPI void glRecti(GLint x1, GLint y1, GLint x2, GLint y2);
GLAPI void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels);
GLAPI void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params);
GLAPI void glPointSize(GLfloat size);
GLAPI void glClipPlane(GLenum plane, GLdouble const* equation);

View file

@ -449,6 +449,11 @@ GLubyte const* glGetString(GLenum name)
return g_gl_context->gl_get_string(name);
}
void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels)
{
g_gl_context->gl_get_tex_image(target, level, format, type, pixels);
}
void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params)
{
g_gl_context->gl_get_tex_parameter_integerv(target, level, pname, params);

View file

@ -194,6 +194,7 @@ public:
void gl_light_model(GLenum pname, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void gl_bitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte const* bitmap);
void gl_copy_tex_image_2d(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
void gl_get_tex_image(GLenum target, GLint level, GLenum format, GLenum type, void* pixels);
void gl_get_tex_parameter_integerv(GLenum target, GLint level, GLenum pname, GLint* params);
void gl_rect(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
void gl_tex_gen(GLenum coord, GLenum pname, GLint param);

View file

@ -11,6 +11,14 @@
namespace GL {
void Texture2D::download_texture_data(GLuint lod, GPU::ImageDataLayout output_layout, GLvoid* pixels)
{
if (device_image().is_null())
return;
device_image()->read_texels(0, lod, { 0, 0, 0 }, pixels, output_layout);
}
void Texture2D::upload_texture_data(GLuint lod, GLenum internal_format, GPU::ImageDataLayout input_layout, GLvoid const* pixels)
{
// NOTE: Some target, format, and internal formats are currently unsupported.

View file

@ -27,6 +27,7 @@ public:
virtual bool is_texture_2d() const override { return true; }
void download_texture_data(GLuint lod, GPU::ImageDataLayout output_layout, GLvoid* pixels);
void upload_texture_data(GLuint lod, GLenum internal_format, GPU::ImageDataLayout input_layout, GLvoid const* pixels);
void replace_sub_texture_data(GLuint lod, GPU::ImageDataLayout input_layout, Vector3<i32> const& output_offset, GLvoid const* pixels);

View file

@ -143,6 +143,36 @@ void GLContext::gl_gen_textures(GLsizei n, GLuint* textures)
}
}
void GLContext::gl_get_tex_image(GLenum target, GLint level, GLenum format, GLenum type, void* pixels)
{
RETURN_WITH_ERROR_IF(level < 0 || level > Texture2D::LOG2_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
auto pixel_type_or_error = get_validated_pixel_type(target, GL_NONE, format, type);
RETURN_WITH_ERROR_IF(pixel_type_or_error.is_error(), pixel_type_or_error.release_error().code());
auto texture_2d = m_active_texture_unit->texture_2d_target_texture();
VERIFY(!texture_2d.is_null());
u32 width = texture_2d->width_at_lod(level);
u32 height = texture_2d->height_at_lod(level);
GPU::ImageDataLayout output_layout = {
.pixel_type = pixel_type_or_error.release_value(),
.packing = get_packing_specification(PackingType::Pack),
.dimensions = {
.width = width,
.height = height,
.depth = 1,
},
.selection = {
.width = width,
.height = height,
.depth = 1,
},
};
texture_2d->download_texture_data(level, output_layout, pixels);
}
void GLContext::gl_get_tex_parameter_integerv(GLenum target, GLint level, GLenum pname, GLint* params)
{
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);