DEADSOFTWARE

check FBO status and fall back to no-fbo if something is wrong
authorfgsfds <pvt.fgsfds@gmail.com>
Tue, 25 Feb 2020 16:01:04 +0000 (19:01 +0300)
committerfgsfds <pvt.fgsfds@gmail.com>
Tue, 25 Feb 2020 16:01:04 +0000 (19:01 +0300)
src/engine/e_graphics.pas
src/game/sdl/g_system.pas
src/game/sdl2/g_system.pas

index de31fa50ea46797507f03521c0fe58429658926a..d9761c13e02a1108c460c82896f7c7beca4e6687 100644 (file)
@@ -62,7 +62,7 @@ type
 procedure e_InitGL();
 procedure e_SetViewPort(X, Y, Width, Height: Word);
 procedure e_ResizeWindow(Width, Height: Integer);
-procedure e_ResizeFramebuffer(Width, Height: Integer);
+function e_ResizeFramebuffer(Width, Height: Integer): Boolean;
 procedure e_BlitFramebuffer(WinWidth, WinHeight: Integer);
 
 procedure e_Draw(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
@@ -379,10 +379,8 @@ begin
  if Height <> nil then Height^ := e_Textures[ID].tx.Height;
 end;
 
-procedure e_ResizeFramebuffer(Width, Height: Integer);
+procedure DestroyFramebuffer;
 begin
-  if e_NoGraphics then Exit;
-
   glBindTexture(GL_TEXTURE_2D, 0);
   glBindRenderbuffer(GL_RENDERBUFFER, 0);
   glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -404,25 +402,67 @@ begin
     glDeleteFramebuffers(1, @e_FBO);
     e_FBO := 0;
   end;
+end;
+
+function e_ResizeFramebuffer(Width, Height: Integer): Boolean;
+begin
+  Result := False;
+
+  if e_NoGraphics then Exit;
+
+  DestroyFramebuffer;
 
   e_FrameW := Width;
   e_FrameH := Height;
 
+  glGetError();
+
   glGenFramebuffers(1, @e_FBO);
 
+  if glGetError() <> GL_NO_ERROR then
+  begin
+    e_LogWriteln('GL: glGenFramebuffers failed');
+    Exit;
+  end;
+
   glGenTextures(1, @e_Frame);
   glBindTexture(GL_TEXTURE_2D, e_Frame);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Width, Height, 0, GL_RGB, GL_UNSIGNED_BYTE, nil);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
-  glGenRenderbuffers(1, @e_RBO);
-  glBindRenderbuffer(GL_RENDERBUFFER, e_RBO);
-  glRenderbufferStorage(GL_RENDERBUFFER, {$IFNDEF USE_GLES1}GL_DEPTH24_STENCIL8{$ELSE}GL_DEPTH_COMPONENT16{$ENDIF}, Width, Height);
+  if glGetError() <> GL_NO_ERROR then
+  begin
+    e_LogWriteln('GL: can''t create FBO color buffer');
+    DestroyFramebuffer;
+    Exit;
+  end;
 
   glBindFramebuffer(GL_FRAMEBUFFER, e_FBO);
   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, e_Frame, 0);
-  glFramebufferRenderbuffer(GL_FRAMEBUFFER, {$IFNDEF USE_GLES1}GL_DEPTH_STENCIL_ATTACHMENT{$ELSE}GL_DEPTH_ATTACHMENT{$ENDIF}, GL_RENDERBUFFER, e_RBO);
+
+{$IFNDEF USE_GLES1}
+  glGenRenderbuffers(1, @e_RBO);
+  glBindRenderbuffer(GL_RENDERBUFFER, e_RBO);
+  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, Width, Height);
+  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, e_RBO);
+  if glCheckFramebufferStatus(GL_FRAMEBUFFER) <> GL_FRAMEBUFFER_COMPLETE then
+  begin
+    e_LogWriteln('GL: can''t construct framebuffer with depth+stencil attachment');
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+    glDeleteRenderbuffers(1, @e_RBO); e_RBO := 0;
+    Exit;
+  end;
+{$ENDIF}
+
+  if glCheckFramebufferStatus(GL_FRAMEBUFFER) <> GL_FRAMEBUFFER_COMPLETE then
+  begin
+    e_LogWriteln('GL: can''t construct framebuffer with color attachment');
+    DestroyFramebuffer;
+    Exit;
+  end;
+
+  Result := True;
 end;
 
 procedure e_ResizeWindow(Width, Height: Integer);
index 7593b02398811605b2981aed31267e8760e8a20c..68f99188a830691b8f2d149e33ad70873d7a3191 100644 (file)
@@ -103,7 +103,13 @@ implementation
       // store real window size in gWinSize, downscale resolution now
       w := round(w / r_pixel_scale);
       h := round(h / r_pixel_scale);
-      e_ResizeFramebuffer(w, h);
+      if not e_ResizeFramebuffer(w, h) then
+      begin
+        e_LogWriteln('GL: could not create framebuffer, falling back to --no-fbo');
+        glRenderToFBO := False;
+        w := gWinSizeX;
+        h := gWinSizeY;
+      end;
     end;
     gScreenWidth := w;
     gScreenHeight := h;
index 31c5b1cde5c4147282cd52211f24446cd9a47e12..992d6dc4c7091de9906f6f9808ef695c7553542c 100644 (file)
@@ -107,7 +107,13 @@ implementation
       // store real window size in gWinSize, downscale resolution now
       w := round(w / r_pixel_scale);
       h := round(h / r_pixel_scale);
-      e_ResizeFramebuffer(w, h);
+      if not e_ResizeFramebuffer(w, h) then
+      begin
+        e_LogWriteln('GL: could not create framebuffer, falling back to --no-fbo');
+        glRenderToFBO := False;
+        w := gWinSizeX;
+        h := gWinSizeY;
+      end;
     end;
     gScreenWidth := w;
     gScreenHeight := h;