Tuesday, October 10, 2023

VHDL Character Generator

The bitmap was saved to 80x60 at 8bpp, allowing the pixel values to index character tiles from a character generator ROM in VHDL. This design slightly improves on my previous project by accounting for the clock delay incurred with the registered address into the BRAM. 

It's not a very good picture, using an old USB capture device which actually goes from VGA through a converter to analog video before it hits the USB device. Cell phone camera will take a better picture.

The tile calculation formula maps an 80x60 tile display of 8x8 character tiles to a 640x480 VGA display. The present design is far from optimized and uses integer math to convert the pixel scan location to a tile address in the simulated VRAM. The synthesis tool infers a DSP to implement a multiplier. The Vivado DRC (design rule checker) flags this DSP implementation with warnings which I would like to eliminate. 



Monday, September 4, 2023

VHDL Bitmap Rendering


This is a brief overview of using VHDL to render bitmap images on a VGA display. It is far from being a complete tutorial on working with VHDL. The presentation was developed using the Xilinx Vivado suite, targeting the Arctix A7 FPGA on the Digilent Basys 3 development board.
 

My first experiment with rendering a bitmap image from an FPGA device was based on using the builtin file I/O operations available in VHDL. In VHDL it is possible to read the content of a bitmap image from a file, parse the bitmap header to obtain the layout of the image (height, width, color encoding etc.), and then populate a ROM entity in VHDL with the bitmap data, and of course build a VHDL circuit around that ROM to render the image to a VGA display. Turns out that this method really slows down the synthesis operation, and even the small image shown above requires several minutes to generate a bitstream for programming the FPGA. However it is quite interesting to see the capability of VHDL code being used not just to describe digital logic circuits, but for "mundane" operations such as file I/O!

For the purpose of designing microprocessor based systems in VHDL, one will no doubt want to write a program for the target CPU, and then have a means to infer a ROM in the VHDL design containing the image of the compiled code. For example, the t80 distribution has a utility program provided by the author called hex2rom that can take a source hex or binary image and generate a suitable VHDL entity. hex2rom works just as well to convert a bitmap file to VHDL and provides options to specify the basic necessary attributes such as endianness, address width and so on. 

First significant problem encountered has to do with using hex2rom to generate ROM in synchronized mode. In many cases, the sync ROM is more desirable as it is more likely to infer a Block RAM. However, hex2rom registers the ROM address internally, which causes the ROM to output a pixel data that is 1 clock behind the screen row/column address from which the pixel address input to the ROM was calculated. Before:


After many days, finally realized from running the simulation what was going on. The fix is to add 1 to the allowed column range of the image enable signal in each scan-line, forcing the image display logic to sync with the actual pixel data coming out of the ROM.  


Hard to explain in words, more details to come. And that's not the last problem to be solved. We also find that Vivado is spewing a lot of warnings related to the BRAM that the synthesis tool has inferred.


In relatively small and simple circuits these warnings can possibly be ignored and the circuit ends up working as intended, but the cause should be understood and corrected. In this case, the tool doesn't think that the address inputs to the inferred BRAM are properly synchronized (the Xilinx Synthesis Tool guide or similar documentation provide a lot of information on how to setup your design to infer properly working BRAMs, without incurring a bunch of DRC warnings!).

Friday, January 24, 2020

pgge: new animation controller

The new animation capability is just kind of hacked in right now. The important part is that the physics body of the rigs now provided by btCompoundShape. This allows me to manipulate the mesh of individual model nodes within the model instance, and then they are magically synced up with bullet so that the collision detection is true to the dynamically changing mesh body. See video!



Wednesday, December 18, 2019

Pretty Good Game Engine is 2 Years Old!

Has a few more features since then ...

  • Pause menu
  • Loading screen
  • Gamepad on Android
  • Bad actors
  • Player can  shoot at and kill some things and even get some points for doing it
  • Prize pickups


Monday, November 11, 2019

Before and after adjust internal edge contacts filtering edge collisions of btvhTriangleMesh


Wednesday, December 26, 2018

Fixed memory leak in pgge

Nasty memory leak has been present for the last 10 months! It was found by running on the Android device, after about 10 minutes the fireworks start:

D/dalvikvm: GC_FOR_ALLOC freed 3603K, 14% free 31246K/36280K, paused 176ms, total 176ms
D/dalvikvm: GC_FOR_ALLOC freed 3585K, 14% free 31666K/36684K, paused 183ms, total 183ms
W/Adreno-GSL: : sharedmem_gpumem_alloc: mmap failed errno 12 Out of memory
E/Adreno-GSL: : GSL MEM ERROR: kgsl_sharedmem_alloc ioctl failed.
W/Adreno-GSL: : sharedmem_gpumem_alloc: mmap failed errno 12 Out of memory
E/Adreno-GSL: : GSL MEM ERROR: kgsl_sharedmem_alloc ioctl failed.
A/libc: Fatal signal 11 (SIGSEGV) at 0x61860398 (code=2), thread 25200 (Thread-2710)
Application terminated.


If one had been paying any attention to the Android console log, it would have been evident that the GC is staying WAY too busy! Creating new instances at every render will definitely leak away the memory! Several hours to find the issue, only a minute to fix it

Tuesday, December 18, 2018

Pretty Good Game Engine is 1 Year Old!

One year ago I started a new github repo, a new programming project using libGDX.

The purpose of the pgge project is to demonstrate the libGDX 3D API and Bullet physics integration in a 3D game engine.

The project is developed using Android Studio for Java development, and Blender to create 3D models. Thanks to libGDX multiplatform capability, the program can be run on an Android device or on PC desktop.

Hope someone has a chance to check it out!


Sunday, April 10, 2016

Compatible OpenGL / OpenGL ES games on i.MX6

If you happen to have an ARM development board sitting around, you may be thinking about plugging it into your nearest HDTV to play some games. While the ultimate gaming computer is probably not going to be built around a single-board computer such as ODROID or Raspberry PIit might be interesting to see what such a device is capable of. I was looking for games that would utilize the OpenGL|ES capability provided by the i.MX6Q processor, but there aren't that many compatible Linux games out there, with most still using the standard "desktop" OpenGL. Many of the similar ARM SOCs provide only GL|ES and do not support OpenGL at all, but the i.MX6Q at least supports some part of the OpenGL 2.1 specification. To help me keep track of the results, I started creating my own "ultimate guide" for GL/GL|ES compatible games on i.MX6Q and maybe others might find this information useful as well.

In order to make my list, I require that the game will run full-screen with "reasonable" FPS, and utilize the hardware GL or GL|ES capability of the i.MX6Q (refer to my previous posts how the system is setup). However, on the Sabre Lite and SabreSD boards that I'm using, I found that many of these games don't set the video mode properly, but it can be done manually using xrandr prior to running the game. I am also trying to keep track of some different monitors that I am using (a 4:3 A/R Dell, a 1920x1080 RCA HDTV, and our new 55" Samsung HDTV), as the aspect ratio may affect what modes are available to the game.

As I mentioned in the introduction above, I found only a couple of games so far that are using GL|ES graphics on Linux, these are:
  • Trigger Rally, ported to OpenGL|ES by ptitSeb (libGLES_CM)
  • Hurrican, ported by pickle (libGLESv2)

The i.MX6Q supports at least a part of OpenGL 2.1 and I have found a half dozen or so titles that are compatible, including an early version of Neverball. I have found quite a few more games that will run if linked to a special implementation of libGL called glshim. The glshim library was devised by lunixbochs for the purpose of "providing OpenGL 1.x functionality to OpenGL ES accelerated cards" (and thus to to expand the available games for the Pandora ... and possibly other platforms). As stated glshim provides "parts of OpenGL 1.x by internally translating to OpenGL ES". By now, glshim has found its way from the Pandora world to other ARM platforms such as Odroid, and i.MX6. I am using the ptitseb branch as I found it would allow a few games to run that the lunixbochs version wouldn't, but at this time I have not bothered to see what the functional differences are between the two versions.

Running the game executable with glshim may be as simple as invoking it with LD_CONFIG_PATH. However, I seem to find that I have to re-link the executable, else it tends to defer to the libGL.so which is already installed on my system. This is easily done be replacing '-lGL' with e.g. '/usr/local/lib/glshim/libGL.so' in the link command.

One final comment is that out of the dozen or so games that I have built and found working with glshim, all are using libSDL-1.2, with the exception of CaveExpress (libSDL2-2.0). 

Enjoy!

Monday, February 29, 2016

Trigger Rally GL|ES on i.MX6Q

Trigger Rally, "a fast-paced free software rally racing game", was ported some time ago to OpenGL|ES on Open Pandora by ptitSeb. Here's a link to the SourceForge browser at Revision: 96 where the Pandora branch was made. With a bit of additional footwork, I was able to build it on an i.MX6 quad-core and it seems to run pretty well. Trigger Rally has undergone considerable development since that branch was made, so it might be a good exercise to forward-port those GL|ES patches to the current version! 

Build Environment
The build environment is hosted on an i.MX6 quad-core platform running Debian “jessie” release. The system relies on closed-source VIVANTE GPU libraries for Freescale i.MX6 being installed. Please see previous posts for details on setting up the root file system to support accelerated GL/GLES functionality in Debian.


Prerequisite  Binary Packages
apt-get install cmake jam libsdl-image1.2-dev libopenal-dev libalut-dev libphysfs-dev

Build GLU ES 
TR depends on GLU ES implementation (gluScaleImage) - latest source ported by lunixbochs (GLU ES version 1.5 based on original GLU 1.3) is on GitHub. 

git clone https://github.com/lunixbochs/glues.git
cd glues ; rm -f CMakeCache.txt ; cmake . ; make

If the build is successful, the library file libGLU.so.1 will have been created. There is no install target - maybe there is better way, but I simply copy the two needed header files so they will be found by the build in a system include path:

cp lunixbochs/glues/source/glues.h  /usr/local/include/GLES/
cp lunixbochs/glues/include/SDL/SDL_opengles.h  /usr/local/include/SDL/

Build TR
Define LINUX in trigger-rally-pandora/Jamrules; otherwise header file /usr/include/EGL/eglvivante.h (part of Freescale imx-gpu-viv bundle) throws an #error "Platform not recognized":

sed -i 's/COMPILER_CFLAGS += -Wall/COMPILER_CFLAGS += -Wall -DLINUX=1/' Jamrules

Please note that this project uses jam (and not make) as build tool:
./configure ; jam

If you did not copy over the header files from GLU ES, you are probably seeing a couple of errors from the build:

src/pengine/pengine.h:39:24: fatal error: GLES/glues.h: No such file or directory

/usr/local/include/GLES/glues.h:37:33: fatal error: SDL/SDL_opengles.h: No such file or directory

Eventually, the linker fails due to library specification -lGLUES_CM:

/usr/bin/ld: cannot find -lGLUES_CM
collect2: error: ld returned 1 exit stat

Rather than take the time to tweak the jam scripts to fix the problem correctly, immediate gratification is had by manually linking the trigger executable in the shell: remove -lGLUES_CM from the linker invocation, as well as the library path specification -L/usr/lib/arm-linux-gnueabihf, and link directly to the GLU  ES library libGLU.so.1 as follows:

g++ -Wall -DLINUX=1 -O3   -DDATADIR='"${prefix}/share"' -DHAVE_GLES -DPANDORA  -o trigger ./out/armv7l-unknown-linux-gnu/opt/src/trigger/eglport.o ./out/armv7l-unknown-linux-gnu/opt/src/trigger/game.o ./out/armv7l-unknown-linux-gnu/opt/src/trigger/main.o ./out/armv7l-unknown-linux-gnu/opt/src/trigger/render.o ./out/armv7l-unknown-linux-gnu/opt/src/trigger/menu.o  ./out/armv7l-unknown-linux-gnu/opt/src/pengine/libpengine.a ./out/armv7l-unknown-linux-gnu/opt/src/psim/libpsim.a   -lSDL -lSDL_image -lEGL -lGLES_CM  -lopenal -lalut -lphysfs ../glues/lunixbochs/glues/libGLU.so.1 

(use jam -n to get the g++ command)

Success!
No need to run the make install, the trigger executable will run fine if invoked from within the project "./data" directory:

cd data ; ln -s ../trigger

xrandr -s 800x600   # TODO: it can't seem to change resolution on it's own!
LIBGL_DEBUG=verbose ./trigger



Enjoy!

Tuesday, January 26, 2016

Hurrican 2D Platformer on i.MX6 Sabrelite

Hurrican is a retro/16-bit styled 2D platformer that I was able to build from source on an i.MX6 Sabrelite board with essentially zero effort, as it has already been ported to SDL 1.2 and GLES2.

Some background info may be of interest on the forum posting at Phoronix. Apparently Hurrican was entirely a Windoze game ported to Linux-SDL-GL by pickle who is pretty active on the Open Pandora Pyra community, which I have been looking at quite a bit lately to research games and GL stuff to try out on the i.MX6 board.

This one builds and runs "out of the box" as they say on my system, with great sound music, keyboard control and no obvious glitches.

Repository Root: svn://svn.code.sf.net/p/hurrican/code

sdl1.2 is installed from the distribution and apparently with GLES2 target enabled ...

apt-get install libsdl-mixer1.2-dev libsdl-image1.2-dev libsdl1.2-dev libmodplug-dev
cd hurrican-code/Hurrican/src/
make TARGET=linux_GL2  # this will link with -lGLESv2

I should get a screenshot of the thing running but even better is gratuitous nerdy console output showing all the startup logging gotta love it ...



More info on Hurrican over at Odroid forum.









Monday, January 25, 2016

mesa demos revisited on i.MX6

In my quest to better understand GL/GLES I previously setup an Debian environment on i.MX6 and installed Freescale support libraries to enable hardware accelerated GL functionality.

Download source for mesa-demos-8.3.0.

Build is done in native armhf environment on the i.MX6 Sabre-lite. With usr libraries and headers installed, the following error is seen in the build:

 /usr/include/EGL/egl.h:39,
                 from eglut.c:32:
/usr/include/EGL/eglvivante.h:242:2: error: #error "Platform not recognized"
 #error "Platform not recognized"

Use the following configure to define platform LINUX:

CFLAGS=-DLINUX ./configure --enable-vg=no

(configure detects "vg" available on my system but throws many compile errors which I don't care to deal with for now so use --enable-vg=no   to avoid additional errors)

The following modules are automatically enabled from the above configure line ... one outcome I didn't check for was situation with GL support (what any header files are supplied with support libraries):
checking for GLEW... yes
checking for GLU... yes
checking for EGL... yes
checking for GLESV1... yes
checking for GLESV2... yes
checking for OSMESA... no
checking for DRM... yes
checking for X11... yes
checking for GBM... yes
checking for FREETYPE2... yes

The following error is seen in the build  ... assume at least in this case it is a benign side affect of co-mingling locally built packages with chip vendor support libraries:

/usr/bin/ld: warning: libGL.so.1, needed by /usr/lib/gcc/arm-linux-gnueabihf/4.9/../../../arm-linux-gnueabihf/libGLEW.so, may conflict with libGL.so.1.2

Demos in src/egl/opengles1src/egl/opengles2 working.
Some in src/demos working, some not, some real slow.
Most in src/tests apparently not ... glutfx full screen but otherwise not interesting.
I noticed from eglinfo that there is no 'gl' context so don't expect anything from src/egl/opengl to work.

debian@arm:~/src/mesa/mesa-demos-8.3.0/src/egl/opengl$ DISPLAY=:0 LIBGL_DEEBUG=verbose ./eglinfo -info
EGL API version: 1.4
EGL vendor string: Vivante Corporation
EGL version string: 1.4
EGL client APIs: OpenGL_ES OpenVG
EGL extensions string:
    EGL_KHR_reusable_sync EGL_KHR_fence_sync EGL_KHR_image
    EGL_KHR_image_base EGL_KHR_image_pixmap EGL_KHR_gl_texture_2D_image
    EGL_KHR_gl_texture_cubemap_image EGL_KHR_gl_renderbuffer_image
    EGL_KHR_lock_surface EGL_KHR_create_context
    EGL_EXT_create_context_robustness EGL_EXT_buffer_age
EGL client extensions string:
Configurations:
     bf lv colorbuffer dp st  ms    vis   cav bi  renderable  supported
  id sz  l  r  g  b  a th cl ns b    id   eat nd gl es es2 vg surfaces 
---------------------------------------------------------------------
0x01 12  0  4  4  4  0  0  0  0 0 0x21--      a     y  y     win,pb
0x02 12  0  4  4  4  0  0  8  0 0 0x21--      a     y  y     win,pb


src/xdemos/glxgears is good to go: 

debian@arm:~/src/mesa/mesa-demos-8.3.0/src/xdemos$ DISPLAY=:0 LIBGL_DEBUG=verbose ./glxgears
libGL: OpenDriver: trying /usr/lib/dri/vivante_dri.so
drmOpenByBusid: Searching for BusID platform:Vivante GCCore:00
drmOpenDevice: node name is /dev/dri/card0
drmOpenDevice: open result is 4, (OK)
drmOpenByBusid: drmOpenMinor returns 4
drmOpenByBusid: drmGetBusid reports platform:Vivante GCCore:00
748 frames in 5.0 seconds = 149.467 FPS
752 frames in 5.0 seconds = 150.196 FPS
^CProcess termination by interupt!
debian@arm:~/src/mesa/mesa-demos-8.3.0/src/xdemos$   


This patch against mesa-demos-8.3.0 incorporates these various hacks and fixes including one known issue regarding undefined reference to `glWindowPos2iARB'.



Good luck!

Sunday, January 24, 2016

HP Omen i7 Quadcore + Ubuntu 15.10 AMD 64

Finally a new computer, first one in a few years.

HP - OMEN 15.6" Touch-Screen Laptop - Intel Core i7 - 8GB Memory - 256GB Solid State Drive on sale at Best Buy.

How annoying is it, machine is unusable until you activate Windows 8 with a Microsoft registration. No matter, here comes Ubuntu 15.10 AMD 64 ...

Using usb-creator, configured a USB flash drive for installing Ubuntu 15.10 AMD 64 ISO.

On power up hold keys FN-F10-ESC, then F9 accesses "Boot Device Options" ().
  • Select "USB Hard Drive (UEFI) - SanDisk Cruzer"
  • On the flash disk Ubuntu boot menu, select "Try Ubuntu without installing" (from "Install Ubuntu" it would not consistently boot from the USB)
All 4 USB ports are on the back of the machine which is occasionally annoying. Several tries to get machine booted from USB, and the boot makes a lot of noise about "Nouveau PIBUS 0xbadf1100" on startup console which seem to hang the machine. When the machine finally booted it locked up several times for no apparent reason and had to be forcibly rebooted. Doesn't seem to be any consistency to this so I suspect (and hope) merely a quirk related to the USB bootable system.

Hang in there and eventually the thing gets booted - waited to plug in HP supplied USB-Ethernet adapter until the machine successfully made all the way to the desktop. Finally, select "Auto Ethernet" from the connections menu (interface is reported by ifconfig as enx0050b67d3ecc).


As far as for configuring the AC 7260 WiFi ... this doesn't seem to work until only after making the modification to modules configuration as shown below (so after OS install this can certainly be fixed,  but use of WiFi during install from Ubuntu 15.10 environment booted from USB stick may be possible by rmmod'ing acer_wmi and related modules and re-configuring the wlo1 interface).


Selected "Download updates while installing".
Did not select "Install the third party software".



Not my screen shot here but as I recall the default partitioning of the 256 Gb SSD drive left about 120 Gb available for a Ubuntu partition - and presumably I won't have problem erasing Windows and re-partitioning and reclaiming 100 or so Gb of SSD. As unpacked out of the box, there is a Windows 8.1 un-activated install - selecting option to Install alongside; subsequent (re)installation attempts do not encounter this dialog but rather the following one (Installation type)  ...


"Installation type" ... "Erase Ubuntu 15.10 and reinstall"


With the following added to /etc/modprobe.d/blacklist.conf, AC 7260 WiFi is working on wlo1 :

blacklist acer_wmi

(Edit: In the live CD environment, rmmod acer_wmi to unload the kernel modules, then restart networking with the command service network-manager restart).

After a bumpy start installing Ubuntu 15.10, once the install process is done it only takes a few seconds to boot the machine. On sporadic occasions the machine fails to boot and returns to the BIOS boot manager a few seconds after attempting Linux boot from the GRUB menu.

One final observation is that on power up the machine always stops at Boot Manager requiring the manual selection of "OS boot Manager (UEFI) - ubuntu (SanDisk SD6PP4M-256G-1006)".

Update: after significant frustration with erratic system hangs, and also reverting to Xubuntu 14.04 in the process, I did some webbing for laptop-suspend problems and got the impression those problems were often related to display drivers. Searching the device "NVIDIA Corporation Device 139b" as reported by lspci yielded some helpful info and having upgraded the video driver from the xorg-edgers ppa the (resume from) suspend seems to work.

Saturday, January 9, 2016

Debian on i.MX6q with GL/GLES

Update notes from previous post - install root file system on i.MX6 from Debian jessie distro and configure GL/GLES. Other people got this working a while before I did so it's mostly a matter of putting all various notes in order. To begin with, keeping links to a few references handy, some resources require registration on Freescale website (as of about 12/2015 will need to update links to NXP domain).

Setup root filesystem

This is for system boot from SD card - with the card already prepped i.e. partitioned, bootloader intsalled, ext4 fs, and mounted e.g. /dev/sda. A suitable debootstrap command to install base Debian root filesystem onto SD card might be:

sudo debootstrap jessie  /media/sda1

On the SabreSD board, I have upgraded to kernel imx_3.14.38_6qp_ga (link to source snapshot tarballs) ... this kernel provides Galcore version 5.0.11. To configure the kernel, I start with 'make imx_v7_defconfig', then make the following additions to .config:

 CONFIG_DRM=m
 CONFIG_DRM_VIVANTE=m

 CONFIG_FHANDLE=y
 CONFIG_EXPORTFS=y
 CONFIG_DEBUG_LL=y
 CONFIG_DEBUG_IMX6Q_UART=y
 CONFIG_EARLY_PRINTK=y

 CONFIG_USB_SERIAL_PL2303=m  # a Prolific USB serial port I'm using

Finish kernel installation to rfs:
 cp arch/arm/boot/zImage  arch/arm/boot/dts/imx6q-sabresd.dtb  /boot/
 echo vivante >> /mnt/sda/etc/modules

Install udev rules configuration file for imx (allow group access to /dev/galcore):
 cp 10.imx-rules /etc/udev/rules.d

Reboot, confirm modules loaded (vivante, drm):
dmesg  | grep Galcore
[    2.421028] Galcore version 5.0.11.33433
ls -l /dev/galcore 
 crw-rw---- 1 root video 199, 0 May 12 21:48 /dev/galcore

I built patched .deb packages for libdrm, mesa, xorg-server to incorporate a critical patch from Freescale for the i.MX6. The idea is that only the packages affected by xfor86drm.h are locally built, and the rest installed from Debian distribution as normal. (Run grep across sources of libdrm, mesa, and xorg-server to see affected files). I'm sure there are more elegant strategies to finesse the local built packages onto the system, but here is a series of commands below demonstrate one attempt to install distribution packages along with local built .debs in the right order to meet package dependencies.  Note -provide simple compile link test for DRM_CAS  defined for arm in running system as well as build environments). Also note latest versions, at this time running X.org X Server 1.16.4 - which seems to work perfectly well without any noticeable incompatibilies (refer to comments regarding Vivante EXA driver below and ignore any instructions on my old blogs to pin the distribution to any previous iteration of snapshot.debian.org).

Create entries in /etc/apt/preferences.d to make apt respect locally built/installed packages e.g. essentially enumerating all the local  debuilded .deb packages:

sabrehd@sabresd:~$ find /etc/apt/preferences.d/
/etc/apt/preferences.d/
/etc/apt/preferences.d/libdrm
/etc/apt/preferences.d/xorg-server
/etc/apt/preferences.d/mesa

Versions of local packages built installed with dpkg and packages apt-getted are all as downloaded  from http://ftp.us.debian.org/debian at the time this system was built and indicated in commands below. To being with, all can be installed from libdrm even though the drm drivers installed have nothing to do with the arm architecture but are harmless and still needed by other modules on the sytem anyway ... dpkg -i `ls libdrm/*\.deb` is of course one way to do it or you could try:

 dpkg -i ./libdrm-freedreno1_2.4.58-2_armhf.deb  libdrm-nouveau2_2.4.58-2_armhf.deb  libdrm-radeon1_2.4.58-2_armhf.deb  libdrm2_2.4.58-2_armhf.deb

At the end there should be a nice xfce4 desktop (a little script might be nice here):

 apt-get  install libllvm3.5  libexpat1 libelf1

 dpkg -i  mesa/libgl1-mesa-dri_10.3.2-1+deb8u1_armhf.deb

 apt-get   install x11-common   libxaw7 libxkbfile1 libxt6 libepoxy0 libpciaccess0 libpixman-1-0 libxfont1 libxshmfence1    xkb-data x11-xkb-utils

 dpkg -i xorg-server/xserver-common_1.16.4-1_all.deb

 apt-get  install keyboard-configuration libx11-xcb1 libxcb-dri2-0 libxcb-dri3-0 libxcb-glx0 libxcb-present0 libxcb-sync1 libxdamage1 libxfixes3 libxxf86vm1   libxcb-render0 libxcb-shape0 libxcb-xfixes0   libwayland-client0 libwayland-server0

 dpkg -i mesa/libglapi-mesa_10.3.2-1+deb8u1_armhf.deb
 dpkg -i mesa/libgbm1_10.3.2-1+deb8u1_armhf.deb
 dpkg -i mesa/libgl1-mesa-glx_10.3.2-1+deb8u1_armhf.deb
 dpkg -i mesa/libegl1-mesa_10.3.2-1+deb8u1_armhf.deb
 dpkg -i ./xorg-server/xserver-xorg-core_1.16.4-1_armhf.deb

 apt-get install  xserver-xorg-video-fbdev xserver-xorg xinit
 apt-get install xfce4

It should be possible to startx at this point. However there are more dev packages to be installed as  the EXA driver for Vivante GPU is also going to be native-built on this system farther below - it's not necessary to native build it (I just don't bother setting up cross-tools), but it must be built I think against the version of X.org release intending to run on the rfs.

 apt-get install libpixman-1-dev x11proto-core-dev x11proto-input-dev x11proto-xext-dev x11proto-video-dev x11proto-randr-dev  x11proto-render-dev x11proto-dri2-dev  x11proto-gl-dev

 apt-get install  x11proto-fonts-dev x11proto-xinerama-dev  x11proto-kb-dev x11proto-xf86dri-dev x11proto-resource-dev x11proto-scrnsaver-dev  x11proto-xf86bigfont-dev  x11proto-dri3-dev x11proto-present-dev

 apt-get install libxkbfile-dev libpciaccess-dev

 dpkg -i ./mesa/mesa-common-dev_10.3.2-1+deb8u1_armhf.deb
 dpkg -i xorg-server/xserver-xorg-dev_1.16.4-1_armhf.deb

Here is the origin of most of the complexity of this system! Note the locations of packages to installed from the FSL Community BSP which can also slightly more conveniently be download directly from yocto project:

http://downloads.yoctoproject.org/mirror/sources/
http://downloads.yoctoproject.org/mirror/sources/xserver-xorg-video-imx-viv-5.0.11.p7.1.tar.gz
http://downloads.yoctoproject.org/mirror/sources/imx-gpu-viv-5.0.11.p7.1-hfp.bin

xserver-xorg-video-imx-viv is source code of Vivante EXA driver (build steps to follow in sections below). imx-gpu-viv is Freescale's implementation of GL/GLES associated runtime libraries and development headers and more or less takes the place of any existing libdrm and mesa implementations on the system - therefore it is likely that installed versions of some of these libs and header files are already on the system. Note that Debian the package management system already installs libGL* and friends to /usr/lib/arm-linux-gnueabihf/, while imx-gpu-viv will wind up in base of /usr/lib which as higher search precedence with ldconfig (the distro versions are not removed).

I used tar to create an archive of imx-gpu-viv-5.0.11.p7.1-hfp/gpu-core/usr/ and to extract the contents over the /usr/ filesystem e.g. resulting in /usr/lib/libGL.so etc. The updated header files are found in /usr/include/GL (should not have any mesa dev packages installed from the distro).

Explanation for the sym-linking scheme, which is done as a way to switch between X11, Wayland or framebuffer versions of the libraries, seems to have been dropped from recent versions of the documentation (i.MX 6Dual/6Quad Linux Reference Manual, Rev. L3.0.35_4.1.0 page 81) but most people in i.MX6 land seem to already be aware of it by now.

On X11 systems, the symbolic links to these libraries need to be redirected. This can be
done using the following sequence of commands:

> cd /usr/lib
> sudo ln -s libGAL-x11.so libGAL.so
> sudo ln -s libEGL-x11.so libEGL.so
> sudo ln -s libEGL-x11.so libEGL.so.1
> sudo ln -s libVIVANTE-x11.so libVIVANTE.so

On directFB backend, the symbolic links to these libraries need to be redirected. This can
be done using the following sequence of commands:

> cd /usr/lib
> sudo ln -s libGAL-dfb.so libGAL.so
> sudo ln -s libEGL-dfb.so libEGL.so
> sudo ln -s libEGL-dfb.so libEGL.so.1
> sudo ln -s libVIVANTE-dfb.so libVIVANTE.so

Note dpkg apt and company have an annoying habit of completing package installs with an invocation of ldconfig which clobbers the links ("sbin/ldconfig.real: /usr/lib/libOpenVG.so is not a symbolic link").

By changing the sim links it should be possible to run some demos on the framebuffer display (imx-gpu-viv-5.0.11.p7.1-hfp/gpu-demos/opt/viv_samples/vdk/) . It is in fact possible to run these in a chroot environment - be sure to use mount -o bind to setup /dev /proc etc. and also, permission 660 on /dev/galcore as mentioned previously allows non-root access to device for owning group (video).

xserver-xorg-video-imx-viv provides the Vivante EXA driver as source code - it must be built against the version of X.org release intending to run on the rfs, and in addition depends on Freescsale's version of libraries and system headers from imx-gpu-viv-5.0.11.p7.1-hfp.bin. The following compile line should work and some additional notes may be useful for troubleshooting problems:

./fastbuild.sh  XSERVER_GREATER_THAN_13=1 BUILD_HARD_VFP=1 BUSID_HAS_NUMBER=1

So what could go wrong?

No such file or directory #include "xorg-server.h" ... this is fixed by installing xserver-xorg-dev (installed from local built .deb) ... note this and other references may need to be modified to #include "xorg/xorg-server.h".

One compile problem that may be encountered in  xserver-xorg-video-imx-viv-5.0.11.p7.1.tar.gz is path to drm.h ... easily corrected in EXA/src/makefile.linux i.e. /usr/include/libdrm/drm.h

Previous versions of xserver-xorg-video-imx tended to have many more compile problems when built against newer versions of X.org, e.g. as shown in the notes below in case the information is useful to anybody. In fact any failures building DRI_1.10.4 can probably be ignored, as this is probably by now already provided by X.org server and is no longer distributed with 5.0.11 series (fastbuild may still try to build it and errors out).

gcc -mfpu=vfp -mfloat-abi=hard -fvisibility=hidden -fPIC -DPIC -I. -I.. -I//usr/include -I//usr/include/xorg -I//usr/include/pixman-1 -I../../EXA/src/vivante_gal -march=armv7-a -marm -o dri.o -c dri.c
dri.c:42:18: fatal error: xf86.h: No such file or directory
 #include "xf86.h"
(Also may need to be changed to "xorg/xf86.h")

makefile.linux:71: recipe for target 'dri.o' failed

DRI_1.10.4/src/drm.h
                 from dri.c:52:
./drm.h:620:26: fatal error: drm/drm_mode.h: No such file or directory


If you got through all that then finally, install the driver, configure X.org server:

 cp src/xserver-xorg-video-imx-viv-3.10.31-1.1.0-beta/EXA/src/vivante_drv.so  /usr/lib/xorg/modules/drivers/
 cp Download/sys/xorg.conf  /usr/share/X11/xorg.conf.d/

... and then hopefully enjoy a successful startx moment:
$ grep VIVANTE:  /var/log/Xorg.0.log
[   188.626] (II) VIVANTE: driver for vivante fb: VivanteGC500, VivanteGC2100,
sabrehd@sabresd:~/Downloads$ 


For bonus points, debuild and install mesa-utils and maybe at least one prerequisite:
sudo dpkg -i mesa/libgles2-mesa_10.3.2-1+deb8u1_armhf.deb
sudo dpkg -i mesa-utils/mesa-utils-extra_8.2.0-1_armhf.deb

Enjoy!

Sunday, March 8, 2015

X.org Patched and Packaged for i.MX6 on Debian

In the previous installment, I described how to build a minimal xserver using X.org modular build script, in order to incorporate a supposedly critical patch to xf86drm.h for the arm architecture. Following on to that experiment, X.org will now be installed mostly from .deb packages, using the Debian package builder to create patched versions of libdrm, mesa, and xorg-server. The motivation for this is to avoid creating a system from a mix of source-built and package-installed software, which generally proves to be a pain to maintain. Unfortunately, for accelerated GPU support, the only viable option is the binary package released by Freescale through the Yocto project - this will introduce another set of headaches (always fighting with ldconfig for priority of /usr/lib/libGL.so etc.), due to not being packaged per Debian or Ubuntu standards. 

Take a look at my previous post.for advice on creating a chroot environment - as is highly recommended for package building - to ensure that the packages are built on a clean system with all dependencies correctly met. The primary purpose of the chroot is solely to make software builds. However, it's worth noting that by the time you work through all the steps, you'll have pretty much everything installed in the chroot to actually run the graphical server. In fact, it's even possible to install and run with GPU acceleration in this chroot configuration (but pretty certain that the GPU support should NOT be installed on the clean build system ... see notes on glmark below).

Configuring this system with the minimum amount of package rebuilding, being very careful of the order of packages installed, and ensuring that the patched packages are actually installed, requires a fair amount of familiarity/creativity with dpkg and aptitude which is not given in great detail here ... may improve or simplify as I expand my knowledge of these tools.

Before entering the chroot environment, it is strongly suggested to create the various standard system mount points - they're not always needed but it's a real good idea: 

sudo mkdir $chroot/run/udev # must be created manually

mount --bind /proc $chroot/proc
mount --bind /run/udev $chroot/run/udev
mount --bind /dev $chroot/dev
mount -t devpts none $chroot/dev/pts
mount --bind /sys $chroot/sys # needed for proper 'LoadModule: "evdev"'

# suggest adding a little sugar to shell prompt in the chroot:
# echo >> $chroot/home/user/.bashrc ...
text=" xorg_drm"
export PS1='\[\e[1;32m\]\u@\h:\w${text}$\[\e[m\] '

With the following additions to $chroot/etc/apt/sources.list, xorg-xserver-1.15.0 will be installed (compatibility with Kernel and i.MX6-Vivante-GPU-blobs 3.10.31 series). :

deb http://snapshot.debian.org/archive/debian/20140320T161557Z/ jessie main
deb-src http://snapshot.debian.org/archive/debian/20140320T161557Z/ jessie main

Using some information found over at hackedbellini to incorporate the following setup:

cat $chroot/etc/apt/preferences.d/xorg-xserver
Package: xserver-*
Pin: origin "snapshot.debian.org"
Pin-Priority: 1001

Force mesa-9.2 series (problems encountered with location of .drirc in mesa-10.1.0, which can probably be sorted out with a little more effort):

Package: *mesa-*
Pin: origin "snapshot.debian.org"
Pin-Priority: 1001

Package: *-mesa*
Pin: origin "snapshot.debian.org"
Pin-Priority: 1001

# Switch into the chroot environment and continue setup ... 
# suppress "Valid-Until" warnings from apt-get:
apt-get -o Acquire::Check-Valid-Until=false update 

# Get some prerequisites installed (there may be more):
apt-get install build-essential fakeroot devscripts

The Debian build system is plenty well documented in other places so expect a lot of details to be glossed over. 

On the build system, a lot of packages will be installed by apt-get build-dep, but there are also notes on packages installed explicitly by apt-get install (but be careful in case the information is not complete). 

Building and installing patched libdrm
By default, the package system will build some sub-modules such as nouveau and radeon that aren't needed on i.MX6, or may have to be present to satisfy other package dependencies. See debian/rules and my previous post for ideas on configurable options that can be disabled. Getting on with it ...

cd pkgsrc/libdrm 
apt-get source libdrm
wget https://raw.githubusercontent.com/Freescale/meta-fsl-arm/master/recipes-graphics/drm/libdrm/mx6/drm-update-arm.patch

cd libdrm-2.4.52
dpkg-checkbuilddeps # not a bad idea to check what dependencies will be installed

apt-get build-dep libdrm

cp  ../drm-update-arm.patch debian/patches/80-drm-update-arm.patch
echo 80-drm-update-arm.patch >> debian/patches/series
debuild -b -uc -us

dpkg-buildpackage -b -j4 -us -uc  # alternative to debuild - note -j option to use those cores!

Should see something like this happening in the configuration phase:

Applying patch 10_drm-update-arm.patch
patching file xf86drm.h

At a minimum, install the following from pkgsrc/libdrm (or just do dpkg -i pkgsrc/*\.deb):

dpkg -i libdrm2_2.4.52-1_armhf.deb libdrm-dev_2.4.52-1_armhf.deb libdrm-nouveau2_2.4.52-1_armhf.deb libdrm-radeon1_2.4.52-1_armhf.deb libdrm-omap1_2.4.52-1_armhf.deb

The arm patch should now be merged into /usr/include/xf86drm.h, verify if unsure!

Building mesa against patched system
By default, the package system will build a kitchen-sink Mesalib ... see debian/rules for the configuration options.

mkdir pkgsrc/mesa
cd pkgsrc/mesa
apt-get source mesa

cd mesa-10.1.0  # todo recheck that I have mesa-10 installed

Make sure libdrm dependencies already met - advise verifying that apt agrees that the libdrm dependencies installed by dpkg are actually installed:
dpkg-checkbuilddeps 

apt-get build-dep mesa  # check first with apt-get -s if super paranoid 

debuild -b -uc -us

An odd thing I noticed, was a second configuration phase in the mesa build ... GLESv2 finally appears on the second pass.

        OpenGL:          yes (ES1: no ES2: no)

        OpenGL:          yes (ES1: yes ES2: yes)


If the mesa build completes successfully, the next module to build is xorg-server, which requires a slew of dependencies to be installed. The freshly built mesa libs should be installed ahead of running apt-get build-dep xorg-server. Suggest first running apt-get -s to verify what will be installed. Pretty sure there is a more efficient way but I don't know the tricks yet.

apt-get install libdrm-freedreno1 libelf1 libexpat1  libllvm3.3 libllvm3.5 libwayland-client0 libwayland-server0  libx11-xcb1 libxcb-dri2-0 libxcb-render0 libxcb-shape0 libxcb-xfixes0  libxfixes3

# here's another batch of 'em that can be knocked out now
apt-get install  keyboard-configuration libfontenc1 libfreetype6 libice6 libpciaccess0 libpixman-1-0 libpng12-0 libsm6  libtxc-dxtn-s2tc0 libxaw7 libxcb-glx0 libxdamage1 libxfont1 libxkbfile1  libxmu6 libxpm4 libxshmfence1 libxt6 libxxf86vm1 x11-common x11-xkb-utils  xfonts-base xfonts-encodings xfonts-utils xkb-data 

# keep going 
apt-get install libpthread-stubs0-dev libx11-dev libx11-doc libx11-xcb-dev libxau-dev  libxcb-dri2-0-dev libxcb-glx0-dev libxcb1-dev libxdamage-dev libxdmcp-dev libxext-dev  libxfixes-dev libxxf86vm-dev x11proto-core-dev x11proto-damage-dev x11proto-dri2-dev  x11proto-fixes-dev x11proto-gl-dev x11proto-input-dev x11proto-kb-dev x11proto-xext-dev  x11proto-xf86vidmode-dev xorg-sgml-doctools xtrans-dev

# At some point, the mesa packages can be installed ... or possibly even the whole shebang:
dpkg -i pkgssrc/mesa/*.deb

# expect dpkg to error out on the following, which should be ok.-
# just clean up the staged installs with dpkg -r
 libgl1-mesa-swx11_9.2.2-1_armhf.deb
 libgl1-mesa-swx11-dev_9.2.2-1_armhf.deb
 libgbm-dev
 libgl1-mesa-swx11-dbg:armhf

Building xorg-server against patched system

mkdir pkgsrc/xorg-server

cd pkgsrc/xorg-server

apt-get source xorg-server
cd xorg-server-1.15.0
dpkg-checkbuilddeps

apt-get build-dep xorg-server

debuild -b -uc -us  # dpkg-buildpackage -b -j4 -us -uc

# build-dep should have installed the needed support, but if not:
# double check not all dependencies needed if omitted these: 
# xdmx xdmx-tools xserver-xephyr

apt-get -s install libpciaccess-dev libpixman-1-dev libxkbfile-dev x11proto-dri3-dev x11proto-fonts-dev x11proto-present-dev x11proto-randr-dev x11proto-render-dev x11proto-resource-dev x11proto-scrnsaver-dev x11proto-video-dev x11proto-xf86bigfont-dev x11proto-xf86dri-dev x11proto-xinerama-dev 

Install away ... all except xdmx xdmx-tools xserver-xephyr

Wrapping it up
It doesn't take much more to get a minimal graphical system running - minimum meaning you only get an xterm - but no WM.

apt-get install keyboard-configuration xserver-xorg-video-fbdev xserver-xorg

# Install at least these from the xserver-xorg builds if you 
# haven't already ...

dpkg -i xserver-common_1.15.0-2_all.deb  xserver-xorg-core_1.15.0-2_armhf.deb xserver-xorg-dev_1.15.0-2_armhf.deb

# ...almost there:

apt-get install xinit

Finally, it should be time for the startX moment. Did it work?

What next?
A few more steps are required to enable GPU acceleration in X11 on i.MX6. For bonus points, build .debs for mesa-utils (glxgears, glxinfo) and mesa-utils-extra (es2gears, es2info). They are dependent upon xf86drm.h, although at this time I haven't confirmed the failure mode of the stock packages built against the unpatched header.

AFAIK, source packages not required for these
apt-get install libglew1.10 libglu1-mesa 

apt-get source mesa-utils
apt-get source mesa-utils-extra

Finally, glmark-es2 seems to be available only in source code. Not a problem! Expect complications to arise with the Yocto packages installed on the system e.g. breaks the glmark-es2 build:


In file included from /usr/include/EGL/eglplatform.h:38:0,
                 from /usr/include/EGL/egl.h:39,
                 from ../src/gl-state-egl.h:26,
                 from ../src/main.cpp:48:
/usr/include/EGL/eglvivante.h:242:2: error: #error "Platform not recognized"
 #error "Platform not recognized"

A working build environment for glmark2 can be created on a chroot filesystem, featuring the patched libdrm and those mesa and xorg-server packages (built against the patched libdrm) installed ... DO NOT install the GPU headers or libs from Yocto on your clean chroot filesystem.

To wrap it up, noting the versions of support packages used so far:
http://downloads.yoctoproject.org/mirror/sources/xserver-xorg-video-imx-viv-3.10.31-1.1.0-beta.tar.gz
http://downloads.yoctoproject.org/mirror/sources/gpu-viv-bin-mx6q-3.10.31-1.1.0-beta-hfp.bin