Results 1 to 6 of 6

Thread: Raspberry Pi + GLES2, anyone?

  1. #1

    Question Raspberry Pi + GLES2, anyone?

    I've basically finished porting my engine (not ready for "your projects" yet) to RPi2.
    I only ever used Raspbian with this tiny wonder.

    In the process I had to learn using a proprietary driver API, converting its headers from C by hand Otherwise there was no hardware acceleration.

    Did anyone else have such problems while doing 3d graphics on RPi using pascal?
    Could it be easier with other OSes ?

    By proprietary API I mean libbcm_host.so and all related Yog-sothothery:

    Code:
      procedure TBroadcomHack.InitEGL(var eDisplay: EGLDisplay;
        var eConfig: EGLConfig;  var eSurface: EGLSurface; var eContext: EGLContext;
        var assumedpfd: TAssumedPFD);
      var
        hr: integer;
        num_config: EGLint;
        Attr: array[0..10] of EGLint = (
          EGL_RED_SIZE, 8,
          EGL_GREEN_SIZE, 8,
          EGL_BLUE_SIZE, 8,
          EGL_ALPHA_SIZE, 8,
          EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
          EGL_NONE);
        CtxAttr:array[0..3] of EGLint = (
          EGL_CONTEXT_CLIENT_VERSION,2,
          EGL_NONE,
          EGL_NONE);
        dispman_alpha: VC_DISPMANX_ALPHA_T;
        scale: float;
        w, h: longint;
      begin
        try
          if Mother^.Debug.Verbose then AddLog('    ..Raspberry Pi detected, creating a Broadcom specific surface...');
    
     // Tested on RPi2, got glitches and flickering at sizes close to 1920 x 1080
     //  - presumably, buffers too large to fit in RAM or something
     // Have to limit.
     // P.S. Changed to making the hardware surface smaller, it got hardware scaling!
          w:= min(VIRTUAL_RES_WIDTH, Mother^.Display.WindowClientRect.Width);
          h:= min(VIRTUAL_RES_HEIGHT_MAX, Mother^.Display.WindowClientRect.Height);
          scale:= min(w / Mother^.Display.WindowClientRect.Width, h / Mother^.Display.WindowClientRect.Height);
    
          AdjustRect(myrect);
            if Mother^.Debug.Verbose then AddLog('    ..Surface rect calculated as %0',[RectToStr(myrect)]);
    
          Mother^.Display.ClientRect.Width:= trunc(scale * myrect.width);
          Mother^.Display.ClientRect.Height:= trunc(scale * myrect.height);
    
            if Mother^.Debug.Verbose then
               AddLog('    .. Hardware surface size %0x%1 (scale %2)',
                 [Mother^.Display.ClientRect.Width, Mother^.Display.ClientRect.Height, scale]);
    
          dst_rect.x:= myrect.left;
          dst_rect.y:= myrect.top;
          dst_rect.width:= myrect.width;
          dst_rect.height:= myrect.height;
    
          src_rect.x:= 0;
          src_rect.y:= 0;
          src_rect.width:= Mother^.Display.ClientRect.Width shl 16;
          src_rect.height:= Mother^.Display.ClientRect.Height shl 16;
    
          dispman_alpha.flags:= DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
          dispman_alpha.opacity:= $FF;
          dispman_alpha.mask:= 0;
    
          dx_dispman_update:= vc_dispmanx_update_start( 0 );
    
          dx_dispman_element:= vc_dispmanx_element_add (
              dx_dispman_update, dx_display_handle,
              0{layer}, @dst_rect, 0{src}, @src_rect,
              DISPMANX_PROTECTION_NONE,
              @dispman_alpha,//nil{alpha},
              nil{clamp}, 0{transform}
          );
    
          f_nativewindow.element:= dx_dispman_element;
          f_nativewindow.width:= myrect.width;
          f_nativewindow.height:= myrect.height;
    
          vc_dispmanx_update_submit_sync( dx_dispman_update );
    
          f_has_surface:= true;
    
          // get an EGL display connection
          eDisplay:= eglGetDisplay(EGL_DEFAULT_DISPLAY);
          if eDisplay = EGL_NO_DISPLAY
            then Die('eglGetDisplay() returned EGL_NO_DISPLAY');
          if Mother^.Debug.Verbose
            then AddLog('  ..display %0',[eDisplay]);
    
          // initialize the EGL display connection
          if 0 = eglInitialize( eDisplay, @f_vmajo, @f_vmino )
            then Die('eglInitialize() failed: ' + EGlErrorCodeToString(eglGetError()));
            if Mother^.Debug.Verbose
              then AddLog('  ..EGL version %0.%1',[f_vmajo, f_vmino]);
    
          // get an appropriate EGL frame buffer configuration
          if 0 = eglGetConfigs(eDisplay, nil, 0, @num_config)
            then Die('eglGetConfigs() faled');
          if Mother^.Debug.Verbose
            then AddLog('  ..#EGL configs %0',[num_config]);
          hr:= eglChooseConfig(eDisplay, @Attr[0], @eConfig, 1, @num_config);
          if (EGL_FALSE = hr) or (num_config <> 1)
            then Die('eglChooseConfig() faled');
    
          assumedpfd.r:= Attr[1];
          assumedpfd.g:= Attr[3];
          assumedpfd.b:= Attr[5];
          assumedpfd.a:= Attr[7];
          assumedpfd.depth:= 0;
          assumedpfd.rect:= myrect;
          assumedpfd.rect.width:= Mother^.Display.ClientRect.Width;
          assumedpfd.rect.height:= Mother^.Display.ClientRect.Height;
    
          // create an EGL rendering context
          eContext:= eglCreateContext(eDisplay, eConfig, EGL_NO_CONTEXT, @CtxAttr[0]);
          if eContext = EGL_NO_CONTEXT
            then Die('eglCreateContext() returned EGL_NO_CONTEXT');
            CheckEGlError();
            if Mother^.Debug.Verbose then AddLog('    ..context %0',[eContext]);
    
          // create an EGL window surface
          eSurface:= eglCreateWindowSurface(eDisplay, eConfig,
            ptruint(@f_nativewindow), //Dirty! native window type boils to TXID,
            //but that's just a fance name for ptruint (see culong)
            //So yes, X handles are opaque pointers too.
            nil);
            if eSurface = EGL_NO_SURFACE then Die(MI_ERROR_CANTINITOPENGL,['eglCreateWindowSurface() returned EGL_NO_SURFACE']);
            CheckEGlError();
            if Mother^.Debug.Verbose then AddLog('    ..surface %0',[eSurface]);
    
    
          if 0 = eglGetConfigs(eDisplay, nil, 0, @num_config)
            then Die(EGlErrorCodeToString(eglGetError()));
    
        except
          Die(RuEn(
            'Не удалось поставить VideoCore костыль для специфичной EGL от Broadcom',
            'Failed to start the VideoCore hack for the peculiar Broadcom EGL'
          ));
        end;
      end;

  2. #2
    As far as I know Platform eXtended library(http://asphyre.net/products/pxl) is the only one that have support for OpenGL ES on Raspberry PI. Whether it uses hardware acceleration for graphics or not that is beyond my knowledge.

    So I guess it would be best if you get in contact with LP (http://www.pascalgamedevelopment.com/member.php?112-LP) which is the author of Platform eXtended Library and exchange experience and knowledge gained when dealing with Raspberry PI.

  3. #3
    That's a good idea.
    Will do when I get my sources in order (them all have GPL comment header when it should be LGPL).

    P.S. I just tested my idea with using hardware scaling (FullHD is too much for RPi 2, it glitches with incomplete buffers ) and it works well indeed.
    I had to add some hacks to my engine to utilize this, such as virtual window client rect (different dimensions from the real client rect)
    When you stretch the window top the whole screen, the render surface stays limited to 1280 width or 960 height, whichever allows for square pixel aspect, and the surface is stretched by hardware to match the window.

    RPi is totally capable of 60 FPS but you have to jump through some hoops to get there.

  4. #4

  5. #5
    Nice. I'm very glad they are doing that. But I am not going to support it, unfortunately.

    There are lots of stuff ToDo in my engine and I barely manage two frameworks: native Win API and native X11. I even had to scrape the planned SDL2 support.
    Supporting RPi was made possible as a manageably limited extension to the X11 framework, but that was the limit of my willingness to invest effort.
    (I need RPi support for bragging rights mostly, I've been previously boasting Windows 98 support but, sadly, outgrew its limitations)

    I should probably have been more clear: I'm interested if anyone did support RPi GLES using other Linuxes than Raspbian (I know there are a few)

  6. #6
    Tried RPi3 + Raspbian 9 Stretch + FPC 3.0.0

    * the DLLs got renamed to libbrcmGLESv2.so libbrcmEGL.so - resolved this by adding these names to the list of DLLs my engine tries. A useful feature, that.
    * the command line options that work changed from
    Code:
     -O3 -CaEABIHF -CpARMV7 -CfVFPV3
    to
    Code:
    -O3 -CaEABIHF -CpARMV7R
    Why...? Who knows.
    * everything else is the same.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •