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.
This commit is contained in:
Jelle Raaijmakers 2022-10-16 19:14:53 +02:00 committed by Linus Groh
parent 0ea4d228e6
commit 0cf3cb6279
4 changed files with 32 additions and 6 deletions

View file

@ -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);
}

View file

@ -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)>;

View file

@ -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)