flyx / OpenGLAda

Thick Ada binding for OpenGL and GLFW
flyx.github.io/OpenGLAda/
MIT License
95 stars 13 forks source link

Problem with gl-objects-programs #129

Closed rogermc2 closed 4 years ago

rogermc2 commented 6 years ago

I just updated my master from upstream/develop. Most examples now fail with a GL.ERRORS.INVALID_OPERATION_ERROR. One of the simplest programs to fail is superbible/simplest/just_a_dot. I traced the source of the problem to common/src/utilities.Show_Shader_Program_Data which seems to fail at Has_Next (List_Cursor) after the last Shaders.Source data has been printed. That is, when the loop should exit as 'Has_Next (List_Cursor)isFalse`. I haven't been able to figure out why this failure occurs.

flyx commented 5 years ago

Just tried to reproduce this. I did some cosmetic changes to accommodate for GNAT Community 2018 and just_a_dot compiled and executed fine on Windows. Can you give me more details?

Maybe you want to wait for me to push my changes upstream so you won't get warnings with the current compiler.

rogermc2 commented 5 years ago

OK. I'll wait for the current updates to be completed before checking again.

flyx commented 5 years ago

Updates now available.

rogermc2 commented 5 years ago

I have just updated my master from upstream/develop but the problem still occurs. I am using the gcc-8.1.0 compiler. What other details might be useful? Maybe I should try GNAT Community 2018?

flyx commented 5 years ago

Could be worth a try. GNAT Community 2018 is based on GCC 7.3.1, so GCC 8.1.0 may make the difference.

rogermc2 commented 5 years ago

Works OK with GNAT Community 2018 on one of my computers but not the other.

flyx commented 5 years ago

Is this still a problem with GNAT Community 2019?

rogermc2 commented 5 years ago

Now a problem on both of my computers with GNAT Community 2019.

rogermc2 commented 4 years ago

This problem remains. I'm not sure what to do about it. Should I try and track it down myself? One example that has the problem is durian/buffers_and_textures.

flyx commented 4 years ago

Should I try and track it down myself?

If you can, please do. As I am not able to reproduce the problem on my machine, it is very hard for me to figure out what goes wrong.

By the way, I added the binder switch -E to OpenGLAda and all examples, which will give you an exception traceback if the program is terminated by an unhandled exception. You can use addr2line / atos (macOS) to convert the traceback addresses to line numbers. Maybe this helps tracking down the error.

rogermc2 commented 4 years ago

OK. It might take me a while. Thanks for the additional debugging tips.

rogermc2 commented 4 years ago

This is my current version of Show_Shader_Program_Data which is probably close to the original although I have tried many modifications in trying to identify the problem. I eventually resorted to the debugger and obtained the backtrace shown below which indicates a problem with finalization on exit from the declare block. I tried using a local procedure instead of the declare block and obtained the same result; that is, the exception occurred during return from the procedure.

I am quite unfamiliar with finalization and need advice on how to proceed further. Thanks for any asssitance that you can provide.

 procedure Show_Shader_Program_Data (aProgram : GL.Objects.Programs.Program) is
      use GL.Objects;
      Shaders_List        : constant Shaders.Lists.List :=
                              Programs.Attached_Shaders (aProgram);
      List_Cursor         : Shaders.Lists.Cursor := Shaders_List.First;
      Shader1             : constant Shaders.Shader :=
                              Shaders.Lists.Element (List_Cursor);
      Shader_Count        : Positive := 1;
   begin
      Put_Line ("Shader: " & Positive'Image (Shader_Count));
      Put_Line (Shaders.Source (Shader1));

      while Shaders.Lists.Has_Next (List_Cursor)  loop
         List_Cursor := Shaders.Lists.Next (List_Cursor);
         declare
            ShaderN  : constant Shaders.Shader :=
                         Shaders.Lists.Element (List_Cursor);
         begin
            Shader_Count := Shader_Count + 1;
            Put_Line ("Shader: " & Positive'Image (Shader_Count));
            Put_Line (Shaders.Source (ShaderN));
         end;
      end loop;
      New_Line;

   exception
      when others =>
         Put_Line ("An exception occurred in Show_Shader_Program_Data.");
         raise;
   end Show_Shader_Program_Data;

Backtrace:

#0  <__gnat_debug_raise_exception> (e=0x1002bfd80 <gl.errors.invalid_operation_error>, message=...) at s-excdeb.adb:43
#1  0x00000001001b7e5d in ada.exceptions.complete_occurrence (x=0x10072aa20) at a-except.adb:931
#2  0x00000001001b7e6d in ada.exceptions.complete_and_propagate_occurrence (x=0x10072aa20) at a-except.adb:942
#3  0x00000001001b7ec2 in <__gnat_raise_exception> (e=0x1002bfd80 <gl.errors.invalid_operation_error>, message=...) at a-except.adb:984
#4  0x00000001001ad2f4 in gl.raise_exception_on_opengl_error () at /System/Volumes/Data/Ada_Source/OpenGLAda/src/gl/implementation/auto_exceptions/gl-raise_exception_on_opengl_error.adb:10
#5  0x0000000100157dbf in gl.objects.shaders.internal_release_id (object=..., id=3) at /System/Volumes/Data/Ada_Source/OpenGLAda/src/gl/implementation/gl-objects-shaders.adb:95
#6  0x000000010016e448 in gl.objects.finalize (object=...) at /System/Volumes/Data/Ada_Source/OpenGLAda/src/gl/implementation/gl-objects.adb:42
#7  0x00000001000cd44c in ?? () at /System/Volumes/Data/Ada_Source/OpenGLAda-examples/common/src/utilities.adb:376
#8  0x00000001000ccfba in utilities.show_shader_program_data (aprogram=...) at /System/Volumes/Data/Ada_Source/OpenGLAda-examples/common/src/utilities.adb:368
#9  0x0000000100004eb9 in main_loop.setup_graphic () at /System/Volumes/Data/Ada_Source/OpenGLAda-examples/durian/buffers_and_textures/src/main_loop.adb:107
#10 0x0000000100004103 in main_loop (main_window=...) at /System/Volumes/Data/Ada_Source/OpenGLAda-examples/durian/buffers_and_textures/src/main_loop.adb:120

utilities.adb:376 is the last line of Show_Shader_Program_Data.

flyx commented 4 years ago

Attached_Shaders returned a list that took ownership of the shader IDs. That lead to this code calling glDeleteShader which isn't its intention. The OpenGL spec allows calling glDeleteShader on shaders attached to a program, which should simply flag them for deletion, and GL_INVALID_OPERATION isn't a valid error generated from it, so this might not be the reason for this error. Still, please check again with the updated code.

rogermc2 commented 4 years ago

I've checked again using the latest pulls from both repositories and the problem remains. (I assume that's what you meant by "updated code") Thanks for the explanation. As to "this might not be the reason for this error", my first idea (which proved incorrect) was that List.Has_Next wasn't working because the loop seemed to be processing the two valid shaders then reentering the loop looking for a third. I added List.Length and List.Current_Cursor functions on my debug branch to investigate this possibility but these indicated that List was OK and that the problem occurs during exit from the declare block. I'll investigate further.

rogermc2 commented 4 years ago

I'm a little confused. Shouldn't the glDeleteShader call be correctly related to the local variable ShaderN, not (incorrectly) to Shaders.Lists.Element (List_Cursor)?

flyx commented 4 years ago

Well before my update, it would be called on each ShaderN but the traceback goes to the end of procedure, so the shader object that's being deleted is Shader1 (the only one living to the end of the procedure).

From what I can see, your project fork misses the commit I made immediately before my comment, so please do update. If the problem still persists, please check the traceback again; since glDeleteShader shouldn't be called anymore, the traceback should at least look different.

rogermc2 commented 4 years ago

You are right! I wasn't updating my fork! I have now remedied that. Your update fixed the problem. Show_Shader_Program_Data now works.