Skip to content

Commit eb7c3d1

Browse files
gmtaawesomekling
authored andcommitted
LibGL+LibGPU+LibSoftGPU: Implement flexible pixel format conversion
A GPU (driver) is now responsible for reading and writing pixels from and to user data. The client (LibGL) is responsible for specifying how the user data must be interpreted or written to. This allows us to centralize all pixel format conversion in one class, `LibSoftGPU::PixelConverter`. For both the input and output image, it takes a specification containing the image dimensions, the pixel type and the selection (basically a clipping rect), and converts the pixels from the input image to the output image. Effectively this means we now support almost all OpenGL 1.5 formats, and all custom logic has disappeared from: - `glDrawPixels` - `glReadPixels` - `glTexImage2D` - `glTexSubImage2D` The new logic is still unoptimized, but on my machine I experienced no noticeable slowdown. :^)
1 parent d7cfdfe commit eb7c3d1

24 files changed

+1350
-705
lines changed

Tests/LibGL/TestRender.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,33 @@ TEST_CASE(0005_lines_antialiased)
169169
context->present();
170170
expect_bitmap_equals_reference(context->frontbuffer(), "0005_lines"sv);
171171
}
172+
173+
TEST_CASE(0006_test_rgb565_texture)
174+
{
175+
auto context = create_testing_context(64, 64);
176+
177+
GLuint texture_id;
178+
glGenTextures(1, &texture_id);
179+
glBindTexture(GL_TEXTURE_2D, texture_id);
180+
u16 texture_data[] = { 0xF800, 0xC000, 0x8000, 0x07E0, 0x0600, 0x0400, 0x001F, 0x0018, 0x0010 };
181+
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
182+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 3, 3, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, texture_data);
183+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
184+
185+
glEnable(GL_TEXTURE_2D);
186+
glBegin(GL_QUADS);
187+
glTexCoord2i(0, 0);
188+
glVertex2i(-1, 1);
189+
glTexCoord2i(0, 1);
190+
glVertex2i(-1, -1);
191+
glTexCoord2i(1, 1);
192+
glVertex2i(1, -1);
193+
glTexCoord2i(1, 0);
194+
glVertex2i(1, 1);
195+
glEnd();
196+
197+
EXPECT_EQ(glGetError(), 0u);
198+
199+
context->present();
200+
expect_bitmap_equals_reference(context->frontbuffer(), "0006_test_rgb565_texture"sv);
201+
}
Binary file not shown.

Userland/Libraries/LibGL/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set(SOURCES
33
ContextParameter.cpp
44
GLAPI.cpp
55
GLContext.cpp
6+
Image.cpp
67
Lighting.cpp
78
List.cpp
89
Matrix.cpp

Userland/Libraries/LibGL/ContextParameter.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,4 +584,28 @@ GLboolean GLContext::gl_is_enabled(GLenum capability)
584584
return parameter.value.boolean_value;
585585
}
586586

587+
GPU::PackingSpecification GLContext::get_packing_specification(PackingType packing_type)
588+
{
589+
// Make use of the fact that the GL_PACK_* and GL_UNPACK_* enum constants are in the exact same order
590+
auto const offset = (packing_type == PackingType::Unpack) ? 0 : (GL_PACK_SWAP_BYTES - GL_UNPACK_SWAP_BYTES);
591+
auto get_packing_value = [&](GLenum packing_parameter) -> GLint {
592+
GLint value;
593+
gl_get_integerv(packing_parameter + offset, &value);
594+
return value;
595+
};
596+
597+
// FIXME: add support for GL_UNPACK_SKIP_PIXELS, GL_UNPACK_SKIP_ROWS and GL_UNPACK_LSB_FIRST
598+
GLint byte_alignment { get_packing_value(GL_UNPACK_ALIGNMENT) };
599+
GLint swap_bytes { get_packing_value(GL_UNPACK_SWAP_BYTES) };
600+
GLint depth_stride { get_packing_value(GL_UNPACK_IMAGE_HEIGHT) };
601+
GLint row_stride { get_packing_value(GL_UNPACK_ROW_LENGTH) };
602+
603+
return {
604+
.depth_stride = static_cast<u32>(depth_stride),
605+
.row_stride = static_cast<u32>(row_stride),
606+
.byte_alignment = static_cast<u8>(byte_alignment),
607+
.component_bytes_order = swap_bytes == GL_TRUE ? GPU::ComponentBytesOrder::Reversed : GPU::ComponentBytesOrder::Normal,
608+
};
609+
}
610+
587611
}

Userland/Libraries/LibGL/GL/gl.h

Lines changed: 77 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ extern "C" {
217217
#define GL_COMPILE_AND_EXECUTE 0x1301
218218

219219
// Type enums
220+
#define GL_BITMAP 0x1A00
220221
#define GL_BYTE 0x1400
221222
#define GL_UNSIGNED_BYTE 0x1401
222223
#define GL_SHORT 0x1402
@@ -228,11 +229,23 @@ extern "C" {
228229
#define GL_3_BYTES 0x1408
229230
#define GL_4_BYTES 0x1409
230231
#define GL_DOUBLE 0x140A
232+
#define GL_HALF_FLOAT 0x140B
233+
#define GL_UNSIGNED_BYTE_3_3_2 0x8032
234+
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
235+
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
236+
#define GL_UNSIGNED_INT_8_8_8_8 0x8035
237+
#define GL_UNSIGNED_INT_10_10_10_2 0x8036
238+
#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
239+
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
240+
#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
241+
#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
242+
#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
243+
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
244+
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
231245
#define GL_BOOL 0x8B56
232246

233247
// Format enums
234248
#define GL_COLOR_INDEX 0x1900
235-
#define GL_COLOR_INDEX8_EXT 0x80E5
236249
#define GL_STENCIL_INDEX 0x1901
237250
#define GL_DEPTH_COMPONENT 0x1902
238251
#define GL_RED 0x1903
@@ -244,21 +257,80 @@ extern "C" {
244257
#define GL_LUMINANCE 0x1909
245258
#define GL_LUMINANCE8 0x8040
246259
#define GL_LUMINANCE_ALPHA 0x190A
247-
#define GL_LUMINANCE8_ALPHA8 0x8045
260+
#define GL_R3_G3_B2 0x2A10
248261
#define GL_BGR 0x80E0
249262
#define GL_BGRA 0x80E1
250-
#define GL_BITMAP 0x1A00
251-
263+
#define GL_ALPHA4 0x803B
264+
#define GL_ALPHA8 0x803C
265+
#define GL_ALPHA12 0x803D
266+
#define GL_ALPHA16 0x803E
267+
#define GL_LUMINANCE4 0x803F
252268
#define GL_LUMINANCE8 0x8040
269+
#define GL_LUMINANCE12 0x8041
270+
#define GL_LUMINANCE16 0x8042
271+
#define GL_LUMINANCE4_ALPHA4 0x8043
272+
#define GL_LUMINANCE6_ALPHA2 0x8044
273+
#define GL_LUMINANCE8_ALPHA8 0x8045
274+
#define GL_LUMINANCE12_ALPHA4 0x8046
275+
#define GL_LUMINANCE12_ALPHA12 0x8047
276+
#define GL_LUMINANCE16_ALPHA16 0x8048
277+
#define GL_INTENSITY 0x8049
278+
#define GL_INTENSITY4 0x804A
253279
#define GL_INTENSITY8 0x804B
254-
#define GL_R3_G3_B2 0x2A10
280+
#define GL_INTENSITY12 0x804C
281+
#define GL_INTENSITY16 0x804D
255282
#define GL_RGB4 0x804F
256283
#define GL_RGB5 0x8050
257284
#define GL_RGB8 0x8051
285+
#define GL_RGB10 0x8052
286+
#define GL_RGB12 0x8053
287+
#define GL_RGB16 0x8054
258288
#define GL_RGBA2 0x8055
259289
#define GL_RGBA4 0x8056
260290
#define GL_RGB5_A1 0x8057
261291
#define GL_RGBA8 0x8058
292+
#define GL_RGB10_A2 0x8059
293+
#define GL_RGBA12 0x805A
294+
#define GL_RGBA16 0x805B
295+
#define GL_COLOR_INDEX8_EXT 0x80E5
296+
#define GL_DEPTH_COMPONENT16 0x81A5
297+
#define GL_DEPTH_COMPONENT16_SGIX 0x81A5
298+
#define GL_DEPTH_COMPONENT24 0x81A6
299+
#define GL_DEPTH_COMPONENT24_SGIX 0x81A6
300+
#define GL_DEPTH_COMPONENT32 0x81A7
301+
#define GL_DEPTH_COMPONENT32_SGIX 0x81A7
302+
#define GL_RG 0x8227
303+
#define GL_COMPRESSED_ALPHA 0x84E9
304+
#define GL_COMPRESSED_ALPHA_ARB 0x84E9
305+
#define GL_COMPRESSED_LUMINANCE 0x84EA
306+
#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
307+
#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
308+
#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
309+
#define GL_COMPRESSED_INTENSITY 0x84EC
310+
#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
311+
#define GL_COMPRESSED_RGB 0x84ED
312+
#define GL_COMPRESSED_RGB_ARB 0x84ED
313+
#define GL_COMPRESSED_RGBA 0x84EE
314+
#define GL_COMPRESSED_RGBA_ARB 0x84EE
315+
#define GL_DEPTH_STENCIL 0x84F9
316+
#define GL_DEPTH_STENCIL_EXT 0x84F9
317+
#define GL_DEPTH_STENCIL_NV 0x84F9
318+
#define GL_SRGB 0x8C40
319+
#define GL_SRGB_EXT 0x8C40
320+
#define GL_SRGB8 0x8C41
321+
#define GL_SRGB8_EXT 0x8C41
322+
#define GL_SRGB_ALPHA 0x8C42
323+
#define GL_SRGB_ALPHA_EXT 0x8C42
324+
#define GL_SRGB8_ALPHA8 0x8C43
325+
#define GL_SRGB8_ALPHA8_EXT 0x8C43
326+
#define GL_SLUMINANCE_ALPHA 0x8C44
327+
#define GL_SLUMINANCE_ALPHA_EXT 0x8C44
328+
#define GL_SLUMINANCE8_ALPHA8 0x8C45
329+
#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
330+
#define GL_SLUMINANCE 0x8C46
331+
#define GL_SLUMINANCE_EXT 0x8C46
332+
#define GL_SLUMINANCE8 0x8C47
333+
#define GL_SLUMINANCE8_EXT 0x8C47
262334

263335
// Lighting related defines
264336
#define GL_LIGHTING 0x0B50
@@ -313,21 +385,6 @@ extern "C" {
313385
#define GL_LINE 0x1B01
314386
#define GL_FILL 0x1B02
315387

316-
// Source pixel data format
317-
#define GL_UNSIGNED_BYTE 0x1401
318-
#define GL_UNSIGNED_BYTE_3_3_2 0x8032
319-
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
320-
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
321-
#define GL_UNSIGNED_INT_8_8_8_8 0x8035
322-
#define GL_UNSIGNED_INT_10_10_10_2 0x8036
323-
#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
324-
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
325-
#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
326-
#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
327-
#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
328-
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
329-
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
330-
331388
// Stencil buffer operations
332389
#define GL_KEEP 0x1E00
333390
#define GL_REPLACE 0x1E01

0 commit comments

Comments
 (0)