diff options
author | Jelle Raaijmakers <jelle@gmta.nl> | 2022-10-16 19:14:53 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-10-16 21:12:15 +0200 |
commit | 0cf3cb62797eeb6f45bb3a9d32f54cdb3df89b29 (patch) | |
tree | 81600d1162ae5f07e6b1e1c2cec15e6e77f2b615 | |
parent | 0ea4d228e6e49e78ddeef623a2799c772e820dd1 (diff) | |
download | serenity-0cf3cb62797eeb6f45bb3a9d32f54cdb3df89b29.zip |
LibGL: Immediately dereference vertex attribute data in display lists
According to the spec, pointers to client data need to be dereferenced
immediately when adding calls such as `glDrawElements` or
`glArrayElement` to a display list. We were trying to support display
lists for these calls but since they only invoke _other_ calls that also
support display lists, we can simply defer the display list
functionality to them.
This fixes the rendering of the ClassiCube port by cflip.
-rw-r--r-- | Tests/LibGL/TestRender.cpp | 26 | ||||
-rw-r--r-- | Tests/LibGL/reference-images/0009_test_draw_elements_in_display_list.qoi | bin | 0 -> 184 bytes | |||
-rw-r--r-- | Userland/Libraries/LibGL/GLContext.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/Vertex.cpp | 9 |
4 files changed, 32 insertions, 6 deletions
diff --git a/Tests/LibGL/TestRender.cpp b/Tests/LibGL/TestRender.cpp index 240f8f23e1..6c26212210 100644 --- a/Tests/LibGL/TestRender.cpp +++ b/Tests/LibGL/TestRender.cpp @@ -252,3 +252,29 @@ TEST_CASE(0008_test_pop_matrix_regression) context->present(); expect_bitmap_equals_reference(context->frontbuffer(), "0008_test_pop_matrix_regression"sv); } + +TEST_CASE(0009_test_draw_elements_in_display_list) +{ + auto context = create_testing_context(64, 64); + + glColor3f(0.f, 0.f, 1.f); + glEnableClientState(GL_VERTEX_ARRAY); + + auto const list_index = glGenLists(1); + glNewList(list_index, GL_COMPILE); + float vertices[] = { 0.f, .5f, -.5f, -.5f, .5f, -.5f }; + glVertexPointer(2, GL_FLOAT, 0, &vertices); + u8 indices[] = { 0, 1, 2 }; + glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, &indices); + glEndList(); + + // Modifying an index here should not have an effect + indices[0] = 2; + + glCallList(list_index); + + EXPECT_EQ(glGetError(), 0u); + + context->present(); + expect_bitmap_equals_reference(context->frontbuffer(), "0009_test_draw_elements_in_display_list"sv); +} diff --git a/Tests/LibGL/reference-images/0009_test_draw_elements_in_display_list.qoi b/Tests/LibGL/reference-images/0009_test_draw_elements_in_display_list.qoi Binary files differnew file mode 100644 index 0000000000..1b4763e884 --- /dev/null +++ b/Tests/LibGL/reference-images/0009_test_draw_elements_in_display_list.qoi diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index 6f780991dd..e068094ba2 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -441,8 +441,6 @@ private: decltype(&GLContext::gl_tex_parameter), decltype(&GLContext::gl_tex_parameterfv), decltype(&GLContext::gl_depth_mask), - decltype(&GLContext::gl_draw_arrays), - decltype(&GLContext::gl_draw_elements), decltype(&GLContext::gl_draw_pixels), decltype(&GLContext::gl_depth_range), decltype(&GLContext::gl_polygon_offset), @@ -473,7 +471,6 @@ private: decltype(&GLContext::gl_color_material), decltype(&GLContext::gl_get_light), decltype(&GLContext::gl_clip_plane), - decltype(&GLContext::gl_array_element), decltype(&GLContext::gl_copy_tex_sub_image_2d), decltype(&GLContext::gl_point_size)>; diff --git a/Userland/Libraries/LibGL/Vertex.cpp b/Userland/Libraries/LibGL/Vertex.cpp index 5e5308fd92..e35c0ab5ff 100644 --- a/Userland/Libraries/LibGL/Vertex.cpp +++ b/Userland/Libraries/LibGL/Vertex.cpp @@ -14,7 +14,8 @@ namespace GL { void GLContext::gl_array_element(GLint i) { - APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_array_element, i); + // NOTE: This always dereferences data; display list support is deferred to the + // individual vertex attribute calls such as `gl_color`, `gl_normal` etc. RETURN_WITH_ERROR_IF(i < 0, GL_INVALID_VALUE); // This is effectively the same as `gl_draw_elements`, except we only output a single @@ -79,7 +80,8 @@ void GLContext::gl_color_pointer(GLint size, GLenum type, GLsizei stride, void c void GLContext::gl_draw_arrays(GLenum mode, GLint first, GLsizei count) { - APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_draw_arrays, mode, first, count); + // NOTE: This always dereferences data; display list support is deferred to the + // individual vertex attribute calls such as `gl_color`, `gl_normal` etc. RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); // FIXME: Some modes are still missing (GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES) @@ -129,7 +131,8 @@ void GLContext::gl_draw_arrays(GLenum mode, GLint first, GLsizei count) void GLContext::gl_draw_elements(GLenum mode, GLsizei count, GLenum type, void const* indices) { - APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_draw_elements, mode, count, type, indices); + // NOTE: This always dereferences data; display list support is deferred to the + // individual vertex attribute calls such as `gl_color`, `gl_normal` etc. RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); // FIXME: Some modes are still missing (GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES) |