patriciogonzalezvivo/glslViewer

[RPi 3B] Saved PNGs are empty (FBO: not complete 36054)

Gutza opened this issue · 4 comments

Gutza commented

I'm unable to capture images on Raspberry Pi using glslViewer despite my best efforts. Whatever I try, I get a fully transparent PNG.

I'm using a Raspberry Pi 3B with 1GB RAM, split equally between the CPU and the GPU:

$ vcgencmd get_mem arm
arm=512M
$ vcgencmd get_mem gpu
gpu=512M

My test frag is as simple as they get:

// test.frag

#ifdef GL_ES
precision mediump float;
#endif

void main() {
    gl_FragColor = vec4(1.0, 0.8, 0.0, 1.0);
}

I need this to run headless, so all my commands start like this (more details on variations later):

glslViewer test.frag --headless --noncurses

If I attach a monitor and I just execute that command I get a yellow screen, as expected. However, if I use any of the capture commands in glslViewer I always get an image or a sequence of images that look like this (note the min, max, and mean values in the Channel statistics section):

# identify is part of imagemagick
$ identify -verbose test.png
Image:
  Filename: test.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: DirectClass
  Geometry: 1920x1080+0+0
  Units: Undefined
  Colorspace: sRGB
  Type: Bilevel
  Base type: Undefined
  Endianness: Undefined
  Depth: 8/1-bit
  Channel depth:
    red: 1-bit
    green: 1-bit
    blue: 1-bit
    alpha: 1-bit
  Channel statistics:
    Pixels: 2073600
    Red:
      min: 0  (0)
      max: 0 (0)
      mean: 0 (0)
      standard deviation: 0 (0)
      kurtosis: -3
      skewness: 0
      entropy: 0
    Green:
      min: 0  (0)
      max: 0 (0)
      mean: 0 (0)
      standard deviation: 0 (0)
      kurtosis: -3
      skewness: 0
      entropy: 0
    Blue:
      min: 0  (0)
      max: 0 (0)
      mean: 0 (0)
      standard deviation: 0 (0)
      kurtosis: -3
      skewness: 0
      entropy: 0
    Alpha:
      min: 0  (0)
      max: 0 (0)
      mean: 0 (0)
      standard deviation: 0 (0)
      kurtosis: -3
      skewness: 0
      entropy: 0
  Image statistics:
    Overall:
      min: 0  (0)
      max: 0 (0)
      mean: 0 (0)
      standard deviation: 0 (0)
      kurtosis: -3
      skewness: 0
      entropy: 0
  Alpha: none   #00000000
  Colors: 1
  Histogram:
    2073600: (0,0,0,0) #00000000 none
  Rendering intent: Perceptual
  Gamma: 0.454545
  Chromaticity:
    red primary: (0.64,0.33)
    green primary: (0.3,0.6)
    blue primary: (0.15,0.06)
    white point: (0.3127,0.329)
  Background color: white
  Border color: srgba(223,223,223,1)
  Matte color: grey74
  Transparent color: none
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 1920x1080+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: Zip
  Orientation: Undefined
  Properties:
    date:create: 2023-03-11T07:56:52+00:00
    date:modify: 2023-03-11T07:56:52+00:00
    png:IHDR.bit-depth-orig: 8
    png:IHDR.bit_depth: 8
    png:IHDR.color-type-orig: 6
    png:IHDR.color_type: 6 (RGBA)
    png:IHDR.interlace_method: 0 (Not interlaced)
    png:IHDR.width,height: 1920, 1080
    png:sRGB: intent=0 (Perceptual Intent)
    signature: 788ae0147bdf979a6575938ca2d7d4403788588f7be2010f03776c968fd1ab49
  Artifacts:
    filename: test.png
    verbose: true
  Tainted: False
  Filesize: 80450B
  Number pixels: 2073600
  Pixels per second: 16.0035MB
  User time: 0.130u
  Elapsed time: 0:01.129
  Version: ImageMagick 6.9.11-60 Q16 aarch64 2021-01-25 https://imagemagick.org

Interestingly, if I execute screenshot interactively in glslViewer's prompt I can actually see the screen go black forever using this frag; if I use glslViewer's default frag (which is time-dependent), the screen only goes black for a moment while it's taking the blank screenshot.

Here are the various CLI commands I attempted, along with their output:

$ rm *.png

$ glslViewer test.frag --headless --noncurses -e screenshot,test.png -e exit
// > FBO: not complete 36054
Screenshot saved to
saving remaining frames to disk, this might take a while ...

$ identify -verbose test.png | grep mean
      mean: 0 (0)
      mean: 0 (0)
      mean: 0 (0)
      mean: 0 (0)
      mean: 0 (0)

$ rm *.png

$ glslViewer test.frag --headless --noncurses -e frames,0,0 -e exit
// [ .................................................. ] 0%
// > FBO: not complete 36054
saving remaining frames to disk, this might take a while ...

$ identify -verbose 00000.png | grep mean
      mean: 0 (0)
      mean: 0 (0)
      mean: 0 (0)
      mean: 0 (0)
      mean: 0 (0)

$ rm *.png

$ glslViewer test.frag --headless --noncurses -e sequence,0,0.001 -e exit
// [ .................................................. ] 0%
// [ ################################################## ] 100%
// > saving remaining frames to disk, this might take a while ...

$ identify -verbose 00000.png | grep mean
      mean: 0 (0)
      mean: 0 (0)
      mean: 0 (0)
      mean: 0 (0)
      mean: 0 (0)

I have tried the following configuration variations with the same results:

  • Raspberry Pi OS Lite (32-bit; an older installation) and Raspberry Pi OS with desktop (64-bit; installed from scratch specifically for glslViewer); both Debian version 11 (bullseye); note that even on the latter I'm booting in CLI, because that's what I need for this project
  • cmake -DNO_X11=TRUE .. and cmake -DNO_X11=TRUE -DFORCE_GBM=TRUE ..
  • dtoverlay=vc4-kms-v3d and dtoverlay=vc4-fkms-v3d in /boot/config.txt

Now here's the kicker: if I just execute

$ glslViewer test.frag --headless --noncurses

and while that's running I also execute raspi2png

$ raspi2png --pngname raspi2png.png

then I do get a proper capture, but only when I use the old dtoverlay=vc4-fkms-v3d:

$ identify -verbose raspi2png.png
Image:
  Filename: raspi2png.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: DirectClass
  Geometry: 1920x1080+0+0
  Units: Undefined
  Colorspace: sRGB
  Type: Palette
  Base type: Undefined
  Endianness: Undefined
  Depth: 8/4-bit
  Channel depth:
    red: 1-bit
    green: 4-bit
    blue: 1-bit
  Channel statistics:
    Pixels: 2073600
    Red:
      min: 255  (1)
      max: 255 (1)
      mean: 255 (1)
      standard deviation: 0 (0)
      kurtosis: 8.189e+51
      skewness: 1e+36
      entropy: 0
    Green:
      min: 204  (0.8)
      max: 204 (0.8)
      mean: 204 (0.8)
      standard deviation: 0 (0)
      kurtosis: -1.54625e+57
      skewness: 5.94562e+39
      entropy: 0
    Blue:
      min: 0  (0)
      max: 0 (0)
      mean: 0 (0)
      standard deviation: 0 (0)
      kurtosis: -3
      skewness: 0
      entropy: 0
  Image statistics:
    Overall:
      min: 0  (0)
      max: 255 (1)
      mean: 153 (0.6)
      standard deviation: 0 (0)
      kurtosis: -1.5
      skewness: -0.59517
      entropy: 0
  Colors: 1
  Histogram:
    2073600: (255,204,0) #FFCC00 srgb(255,204,0)
  Rendering intent: Perceptual
  Gamma: 0.454545
  Chromaticity:
    red primary: (0.64,0.33)
    green primary: (0.3,0.6)
    blue primary: (0.15,0.06)
    white point: (0.3127,0.329)
  Background color: white
  Border color: srgb(223,223,223)
  Matte color: grey74
  Transparent color: black
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 1920x1080+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: Zip
  Orientation: Undefined
  Properties:
    date:create: 2023-03-11T08:20:16+00:00
    date:modify: 2023-03-11T08:20:16+00:00
    png:IHDR.bit-depth-orig: 8
    png:IHDR.bit_depth: 8
    png:IHDR.color-type-orig: 2
    png:IHDR.color_type: 2 (Truecolor)
    png:IHDR.interlace_method: 0 (Not interlaced)
    png:IHDR.width,height: 1920, 1080
    png:sRGB: intent=0 (Perceptual Intent)
    signature: 1735f9ad4f3d94df29d4e49aec54618a62f616603f304685306923d4b09d6d8d
  Artifacts:
    filename: raspi2png.png
    verbose: true
  Tainted: False
  Filesize: 8575B
  Number pixels: 2073600
  Pixels per second: 14698700B
  User time: 0.150u
  Elapsed time: 0:01.141
  Version: ImageMagick 6.9.11-60 Q16 aarch64 2021-01-25 https://imagemagick.org
Gutza commented

I experimented with a few older versions of glslViewer; went back as far as v2.2.1, and the behavior is the same. I think the problem is caused by an external library or configuration directive, but I can't even figure out where to begin investigating this further.

Gutza commented

A (probably unrelated) issue I noticed while building glslViewer repeatedly: executing cmake the first time always fails, and the second time it works with no change whatsoever on my part:

$ rm -rf build && mkdir build && cd build

$ # First attempt
$ cmake -DNO_X11=TRUE ..
-- The CXX compiler identification is GNU 10.2.1
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Could NOT find BROADCOM (missing: BCM_EGL BCM_GLESv2)
-- PLATFORM RASPBERRYPI
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Could NOT find FFMPEG (missing: FFMPEG_LIBRARIES FFMPEG_INCLUDE_DIRS)
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2")
-- Checking for modules 'libavdevice;libavfilter;libavformat;libavcodec;libswresample;libswscale;libavutil'
--   No package 'libavdevice' found
--   No package 'libavfilter' found
--   No package 'libavformat' found
--   No package 'libavcodec' found
--   No package 'libswresample' found
--   No package 'libswscale' found
--   No package 'libavutil' found
-- USING DRM and GBM DRIVERS
-- Found DRM: /usr/include/libdrm
-- Found GBM: /usr/lib/aarch64-linux-gnu/libgbm.so (found version "20.3.5")
-- Performing Test GBM_HAS_BO_MAP
CMake Error at /usr/share/cmake-3.18/Modules/CheckCSourceCompiles.cmake:109 (try_compile):
  Unknown extension ".c" for file

    /home/bogdan/glslViewer/build/CMakeFiles/CMakeTmp/src.c

  try_compile() works only for enabled languages.  Currently these are:

    CXX

  See project() command to enable other languages.
Call Stack (most recent call first):
  deps/vera/cmake/FindGBM.cmake:34 (check_c_source_compiles)
  deps/vera/src/CMakeLists.txt:177 (find_package)


-- Performing Test GBM_HAS_BO_MAP - Failed
-- Performing Test GBM_HAS_MODIFIERS
CMake Error at /usr/share/cmake-3.18/Modules/CheckCSourceCompiles.cmake:109 (try_compile):
  Unknown extension ".c" for file

    /home/bogdan/glslViewer/build/CMakeFiles/CMakeTmp/src.c

  try_compile() works only for enabled languages.  Currently these are:

    CXX

  See project() command to enable other languages.
Call Stack (most recent call first):
  deps/vera/cmake/FindGBM.cmake:42 (check_c_source_compiles)
  deps/vera/src/CMakeLists.txt:177 (find_package)


-- Performing Test GBM_HAS_MODIFIERS - Failed
-- Found EGL: /usr/lib/aarch64-linux-gnu/libEGL.so (found version "1.5")
-- KHR/usr/include
-- Found GLESv2: /usr/lib/aarch64-linux-gnu/libGLESv2.so
-- EGL_INCLUDE_DIRS:       /usr/include
-- EGL_LIBRARIES:          /usr/lib/aarch64-linux-gnu/libEGL.so
-- GLESv2_INCLUDE_DIRS:    /usr/include;/usr/include
-- GLESv2_LIBRARIES:       /usr/lib/aarch64-linux-gnu/libGLESv2.so
-- If you are using the static library build, please keep in mind (and inform yourself of the implications) that liblo is licensed with LGPL v2.1+.
-- The C compiler identification is GNU 10.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Looking for poll
-- Looking for poll - found
-- Looking for select
-- Looking for select - found
-- Looking for getifaddrs
-- Looking for getifaddrs - found
-- Looking for inet_pton
-- Looking for inet_pton - found
-- Check how to print long long int
-- Check if the system is big endian
-- Searching 16 bit integer
-- Looking for sys/types.h
-- Looking for sys/types.h - found
-- Looking for stdint.h
-- Looking for stdint.h - found
-- Looking for stddef.h
-- Looking for stddef.h - found
-- Check size of unsigned short
-- Check size of unsigned short - done
-- Searching 16 bit integer - Using unsigned short
-- Check if the system is big endian - little endian
-- Could NOT find Curses (missing: CURSES_LIBRARY CURSES_INCLUDE_PATH)
-- package_details.cmake: your architecture is arm64
-- Configuring incomplete, errors occurred!
See also "/home/bogdan/glslViewer/build/CMakeFiles/CMakeOutput.log".
See also "/home/bogdan/glslViewer/build/CMakeFiles/CMakeError.log".

$ # Second attempt
$ cmake -DNO_X11=TRUE ..
-- Could NOT find BROADCOM (missing: BCM_EGL BCM_GLESv2)
-- PLATFORM RASPBERRYPI
-- Could NOT find FFMPEG (missing: FFMPEG_LIBRARIES FFMPEG_LIBRARY_DIRS FFMPEG_INCLUDE_DIRS)
-- Checking for modules 'libavdevice;libavfilter;libavformat;libavcodec;libswresample;libswscale;libavutil'
--   No package 'libavdevice' found
--   No package 'libavfilter' found
--   No package 'libavformat' found
--   No package 'libavcodec' found
--   No package 'libswresample' found
--   No package 'libswscale' found
--   No package 'libavutil' found
-- USING DRM and GBM DRIVERS
-- KHR/usr/include
-- EGL_INCLUDE_DIRS:       /usr/include
-- EGL_LIBRARIES:          /usr/lib/aarch64-linux-gnu/libEGL.so
-- GLESv2_INCLUDE_DIRS:    /usr/include;/usr/include
-- GLESv2_LIBRARIES:       /usr/lib/aarch64-linux-gnu/libGLESv2.so
-- If you are using the static library build, please keep in mind (and inform yourself of the implications) that liblo is licensed with LGPL v2.1+.
-- Could NOT find Curses (missing: CURSES_LIBRARY CURSES_INCLUDE_PATH)
-- package_details.cmake: your architecture is arm64
-- Configuring done
-- Generating done
-- Build files have been written to: /home/bogdan/glslViewer/build
Gutza commented

I also noticed something else while playing around with the LYGIA Shader examples; I think this is related to the original issue:

  • The PBR Glass (material) example works (and displays correctly, except that the angle is wrong, for some reason):

    $ glslViewer assets/dragon.obj lighting_pbrGlass.frag -e camera_position,1.43923,-0.891203,-1.98093
    // > exit
  • The Shadow (material) example issues a single FBO not complete error, and displays a partially rendered image (very flat-looking, greyed out):

    glslViewer assets/dragon.obj lighting_shadow.frag -e camera_position,1.43923,-0.891203,-1.98093
    FBO: not complete 36054
    // > exit
  • The Sample DoF example issues three FBO not complete errors, and displays a black screen:

    $ glslViewer sample_dof.frag assets/dragon.obj -C assets/Arches_E_PineTree_3k.hdr -e camera_position,-1.43923,0.891203,1.98093
    // assets/Arches_E_PineTree_3k.hdr loaded as:
    uniform samplerCube u_cubeMap;
    uniform vec3        u_SH[9];
    FBO: not complete 36054
    FBO: not complete 36054
    FBO: not complete 36054
    // > exit
  • The View Position (pass) example issues several FBO not complete errors, and displays a black screen:

    glslViewer assets/dragon.obj lighting_position.frag -e camera_position,1.43923,-0.891203,-1.98093
    FBO: not complete 36054
    FBO: not complete 36054
    FBO: not complete 36054
    FBO: not complete 36054
    FBO: not complete 36054
    FBO: not complete 36054
    // > exit
Gutza commented

Final findings for today: I added some debugging statements in deps/vera/src/gl/fbo.cpp just before the error message and I got this:

$ glslViewer simple.frag -e screenshot,test.png -e exit
// >
GL_DEPTH_COMPONENT32_OES
w=1920, h=1080
FBO: not complete 36054
Screenshot saved to
saving remaining frames to disk, this might take a while ...

where w is m_width, h is m_height, and GL_DEPTH_COMPONENT32_OES is the setting for depth_format.