Browse Source

more robust copy-to-texture

David Rose 17 years ago
parent
commit
7e5c276403

+ 25 - 11
panda/src/display/graphicsOutput.cxx

@@ -1007,9 +1007,13 @@ clear(Thread *current_thread) {
 //  Description: For all textures marked RTM_copy_texture,
 //               RTM_copy_ram, RTM_triggered_copy_texture, or
 //               RTM_triggered_copy_ram, do the necessary copies.
+//
+//               Returns true if all copies are successful, false
+//               otherwise.
 ////////////////////////////////////////////////////////////////////
-void GraphicsOutput::
+bool GraphicsOutput::
 copy_to_textures() {
+  bool okflag = true;
   for (int i=0; i<count_textures(); i++) {
     RenderTextureMode rtm_mode = get_rtm_mode(i);
     if ((rtm_mode == RTM_none)||(rtm_mode == RTM_bind_or_copy)) {
@@ -1018,7 +1022,7 @@ copy_to_textures() {
 
     Texture *texture = get_texture(i);
     PStatTimer timer(_copy_texture_pcollector);
-    nassertv(has_texture());
+    nassertr(has_texture(), false);
 
     if ((rtm_mode == RTM_copy_texture)||
         (rtm_mode == RTM_copy_ram)||
@@ -1036,27 +1040,37 @@ copy_to_textures() {
         buffer = _gsg->get_render_buffer(get_draw_buffer_type(),
                                          get_fb_properties());
       }
-      
+
+      bool copied = false;
       if (_cube_map_dr != (DisplayRegion *)NULL) {
         if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) {
-          _gsg->framebuffer_copy_to_ram(texture, _cube_map_index,
-                                        _cube_map_dr, buffer);
+          copied = 
+            _gsg->framebuffer_copy_to_ram(texture, _cube_map_index,
+                                          _cube_map_dr, buffer);
         } else {
-          _gsg->framebuffer_copy_to_texture(texture, _cube_map_index,
-                                            _cube_map_dr, buffer);
+          copied =
+            _gsg->framebuffer_copy_to_texture(texture, _cube_map_index,
+                                              _cube_map_dr, buffer);
         }
       } else {
         if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) {
-          _gsg->framebuffer_copy_to_ram(texture, _cube_map_index,
-                                        _default_display_region, buffer);
+          copied = 
+            _gsg->framebuffer_copy_to_ram(texture, _cube_map_index,
+                                          _default_display_region, buffer);
         } else {
-          _gsg->framebuffer_copy_to_texture(texture, _cube_map_index,
-                                            _default_display_region, buffer);
+          copied = 
+            _gsg->framebuffer_copy_to_texture(texture, _cube_map_index,
+                                              _default_display_region, buffer);
         }
       }
+      if (!copied) {
+        okflag = false;
+      }
     }
   }
   _trigger_copy = false;
+  
+  return okflag;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/display/graphicsOutput.h

@@ -214,7 +214,7 @@ public:
 protected:
   virtual void pixel_factor_changed();
   void prepare_for_deletion();
-  void copy_to_textures();
+  bool copy_to_textures();
   
   INLINE void begin_frame_spam(FrameMode mode);
   INLINE void end_frame_spam(FrameMode mode);

+ 24 - 15
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -1398,7 +1398,7 @@ end_draw_primitives() {
 //               If z > -1, it is the cube map index into which to
 //               copy.
 ////////////////////////////////////////////////////////////////////
-void DXGraphicsStateGuardian8::
+bool DXGraphicsStateGuardian8::
 framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
                             const RenderBuffer &rb) {
   set_read_buffer(rb);
@@ -1413,23 +1413,22 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   
   TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
   if (tc == (TextureContext *)NULL) {
-    return;
+    return false;
   }
   DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc);
 
   if (tex->get_texture_type() != Texture::TT_2d_texture) {
     // For a specialty texture like a cube map, go the slow route
     // through RAM for now.
-    framebuffer_copy_to_ram(tex, z, dr, rb);
-    return;
+    return framebuffer_copy_to_ram(tex, z, dr, rb);
   }
-  nassertv(dtc->get_d3d_2d_texture() != NULL);
+  nassertr(dtc->get_d3d_2d_texture() != NULL, false);
 
   IDirect3DSurface8 *tex_level_0;
   hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0);
   if (FAILED(hr)) {
     dxgsg8_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
-    return;
+    return false;
   }
 
   // If the texture is the wrong size, we need to do something about it.
@@ -1438,7 +1437,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   if (FAILED(hr)) {
     dxgsg8_cat.error() << "GetDesc failed in copy_texture" << D3DERRORSTRING(hr);
     SAFE_RELEASE(tex_level_0);
-    return;
+    return false;
   }
   if ((texdesc.Width != tex->get_x_size())||(texdesc.Height != tex->get_y_size())) {
     if ((orig_x != tex->get_x_size()) || (orig_y != tex->get_y_size())) {
@@ -1448,18 +1447,18 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
         // Oops, we can't re-create the texture for some reason.
         dxgsg8_cat.error()
           << "Unable to re-create texture " << *dtc->get_texture() << endl;
-        return;
+        return false;
       }
       hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0);
       if (FAILED(hr)) {
         dxgsg8_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
-        return;
+        return false;
       }
       hr = tex_level_0->GetDesc(&texdesc);
       if (FAILED(hr)) {
         dxgsg8_cat.error() << "GetDesc 2 failed in copy_texture" << D3DERRORSTRING(hr);
         SAFE_RELEASE(tex_level_0);
-        return;
+        return false;
       }
     }
     if ((texdesc.Width != tex->get_x_size())||(texdesc.Height != tex->get_y_size())) {
@@ -1468,7 +1467,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
       dxgsg8_cat.error()
         << "Unable to copy to texture, texture is wrong size: " << *dtc->get_texture() << endl;
       SAFE_RELEASE(tex_level_0);
-      return;
+      return false;
     }
   }
 
@@ -1477,7 +1476,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   if (FAILED(hr)) {
     dxgsg8_cat.error() << "GetRenderTgt failed in copy_texture" << D3DERRORSTRING(hr);
     SAFE_RELEASE(tex_level_0);
-    return;
+    return false;
   }
 
   RECT src_rect;
@@ -1488,14 +1487,24 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   src_rect.bottom = yo+h;
 
   // now copy from fb to tex
+  bool okflag = true;
   hr = _d3d_device->CopyRects(render_target, &src_rect, 1, tex_level_0, 0);
   if (FAILED(hr)) {
-    dxgsg8_cat.error()
-      << "CopyRects failed in copy_texture" << D3DERRORSTRING(hr);
+    dxgsg8_cat.info()
+      << "CopyRects failed in copy_texture " << D3DERRORSTRING(hr);
+    okflag = framebuffer_copy_to_ram(tex, z, dr, rb);
   }
 
   SAFE_RELEASE(render_target);
   SAFE_RELEASE(tex_level_0);
+
+  if (!okflag) {
+    // The copy failed.  Fall back to copying it to RAM and back.
+    // Terribly slow, but what are you going to do?
+    return framebuffer_copy_to_ram(tex, z, dr, rb);
+  }
+
+  return true;
 }
 
 
@@ -1594,7 +1603,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
       return false;
     }
 
-    copy_inverted = true;
+    //    copy_inverted = true;
 
     RELEASE(backbuffer, dxgsg8, "backbuffer", RELEASE_ONCE);
 

+ 1 - 1
panda/src/dxgsg8/dxGraphicsStateGuardian8.h

@@ -94,7 +94,7 @@ public:
                            bool force);
   virtual void end_draw_primitives();
 
-  virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
+  virtual bool framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
                                            const RenderBuffer &rb);
   virtual bool framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
                                        const RenderBuffer &rb);

+ 54 - 97
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -2049,7 +2049,7 @@ end_draw_primitives() {
 //               If z > -1, it is the cube map index into which to
 //               copy.
 ////////////////////////////////////////////////////////////////////
-void DXGraphicsStateGuardian9::
+bool DXGraphicsStateGuardian9::
 framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
                             const RenderBuffer &rb) {
   set_read_buffer(rb);
@@ -2062,33 +2062,27 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   dr->get_region_pixels_i(xo, yo, w, h);
   tex->set_size_padded(w, h);
 
-  bool use_stretch_rect;
-
-  use_stretch_rect = true;
-  if (use_stretch_rect) {
-    // must use a render target type texture for StretchRect
-    tex -> set_render_to_texture (true);
-  }
+  // must use a render target type texture for StretchRect
+  tex->set_render_to_texture(true);
 
   TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
   if (tc == (TextureContext *)NULL) {
-    return;
+    return false;
   }
   DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc);
 
   if (tex->get_texture_type() != Texture::TT_2d_texture) {
     // For a specialty texture like a cube map, go the slow route
     // through RAM for now.
-    framebuffer_copy_to_ram(tex, z, dr, rb);
-    return;
+    return framebuffer_copy_to_ram(tex, z, dr, rb);
   }
-  nassertv(dtc->get_d3d_2d_texture() != NULL);
+  nassertr(dtc->get_d3d_2d_texture() != NULL, false);
 
   IDirect3DSurface9 *tex_level_0;
   hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0);
   if (FAILED(hr)) {
     dxgsg9_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
-    return;
+    return false;
   }
 
   // If the texture is the wrong size, we need to do something about it.
@@ -2097,7 +2091,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   if (FAILED(hr)) {
     dxgsg9_cat.error() << "GetDesc failed in copy_texture" << D3DERRORSTRING(hr);
     SAFE_RELEASE(tex_level_0);
-    return;
+    return false;
   }
   if ((texdesc.Width != tex->get_x_size())||(texdesc.Height != tex->get_y_size())) {
     if ((orig_x != tex->get_x_size()) || (orig_y != tex->get_y_size())) {
@@ -2107,18 +2101,18 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
         // Oops, we can't re-create the texture for some reason.
         dxgsg9_cat.error()
           << "Unable to re-create texture " << *dtc->get_texture() << endl;
-        return;
+        return false;
       }
       hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0);
       if (FAILED(hr)) {
         dxgsg9_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
-        return;
+        return false;
       }
       hr = tex_level_0->GetDesc(&texdesc);
       if (FAILED(hr)) {
         dxgsg9_cat.error() << "GetDesc 2 failed in copy_texture" << D3DERRORSTRING(hr);
         SAFE_RELEASE(tex_level_0);
-        return;
+        return false;
       }
     }
     if ((texdesc.Width != tex->get_x_size())||(texdesc.Height != tex->get_y_size())) {
@@ -2127,7 +2121,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
       dxgsg9_cat.error()
         << "Unable to copy to texture, texture is wrong size: " << *dtc->get_texture() << endl;
       SAFE_RELEASE(tex_level_0);
-      return;
+      return false;
     }
   }
 
@@ -2143,7 +2137,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
       << "GetRenderTarget failed in framebuffer_copy_to_texture"
       << D3DERRORSTRING(hr);
     SAFE_RELEASE(tex_level_0);
-    return;
+    return false;
   }
 
   RECT src_rect;
@@ -2157,69 +2151,31 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
 //  hr = _d3d_device->CopyRects(render_target, &src_rect, 1, tex_level_0, 0);
 
 //  DX9
-  if (use_stretch_rect) {
-    D3DTEXTUREFILTERTYPE filter;
-
-    filter = D3DTEXF_POINT;
+  D3DTEXTUREFILTERTYPE filter;
 
-//    dxgsg9_cat.debug () << "framebuffer_copy_to_texture\n";
+  filter = D3DTEXF_POINT;
 
-    hr = _d3d_device->StretchRect (
-      render_target,
-      &src_rect,
-      tex_level_0,
-      &src_rect,
-      filter);
-    if (FAILED(hr)) {
-      dxgsg9_cat.error()
-        << "StretchRect failed in framebuffer_copy_to_texture"
-        << D3DERRORSTRING(hr);
-      return;
-    }
+  bool okflag = true;
+  hr = _d3d_device->StretchRect(render_target, &src_rect,
+                                tex_level_0, &src_rect,
+                                filter);
+  if (FAILED(hr)) {
+    dxgsg9_cat.debug()
+      << "StretchRect failed in framebuffer_copy_to_texture"
+      << D3DERRORSTRING(hr);
+    okflag = false;
   }
-  else {
-    //  this is not efficient since it copies the entire render
-    //  target to system memory and then copies the rectangle to the texture
-    // create a surface in system memory that is a duplicate of the render target
-    D3DPOOL pool;
-    IDirect3DSurface9 *temp_surface = NULL;
-    D3DSURFACE_DESC surface_description;
-
-    render_target -> GetDesc (&surface_description);
-
-    pool = D3DPOOL_SYSTEMMEM;
-    hr = _d3d_device->CreateOffscreenPlainSurface(
-           surface_description.Width,
-           surface_description.Height,
-           surface_description.Format,
-           pool,
-           &temp_surface,
-           NULL);
-    if (FAILED(hr)) {
-      dxgsg9_cat.error()
-        << "CreateOffscreenPlainSurface failed in framebuffer_copy_to_texture"
-        << D3DERRORSTRING(hr);
-      return;
-    }
-
-    // this copies the entire render target into system memory
-    hr = _d3d_device -> GetRenderTargetData (render_target, temp_surface);
-
-    if (FAILED(hr)) {
-      dxgsg9_cat.error() << "GetRenderTargetData failed" << D3DERRORSTRING(hr);
-      RELEASE(temp_surface, dxgsg9, "temp_surface", RELEASE_ONCE);
-      return;
-    }
 
-    // copy system memory version to texture
-    DXTextureContext9::d3d_surface_to_texture(src_rect, temp_surface,
-                false, tex, z);
+  SAFE_RELEASE(render_target);
+  SAFE_RELEASE(tex_level_0);
 
-    RELEASE(temp_surface, dxgsg9, "temp_surface", RELEASE_ONCE);
+  if (!okflag) {
+    // The copy failed.  Fall back to copying it to RAM and back.
+    // Terribly slow, but what are you going to do?
+    return framebuffer_copy_to_ram(tex, z, dr, rb);
   }
 
-  SAFE_RELEASE(render_target);
-  SAFE_RELEASE(tex_level_0);
+  return true;
 }
 
 
@@ -2234,7 +2190,8 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
 //               indicated texture.
 ////////////////////////////////////////////////////////////////////
 bool DXGraphicsStateGuardian9::
-framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb) {
+framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, 
+                        const RenderBuffer &rb) {
   set_read_buffer(rb);
 
   RECT rect;
@@ -2291,7 +2248,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
     // GetBackBuffer().  Might just be related to the swap_chain
     // thing.
 
-  render_target_index = 0;
+    render_target_index = 0;
     hr = _d3d_device->GetRenderTarget(render_target_index, &backbuffer);
 
     if (FAILED(hr)) {
@@ -2302,30 +2259,29 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
     // Since we might not be able to Lock the back buffer, we will
     // need to copy it to a temporary surface of the appropriate type
     // first.
-  D3DPOOL pool;
-  D3DSURFACE_DESC surface_description;
+    D3DPOOL pool;
+    D3DSURFACE_DESC surface_description;
 
-  backbuffer -> GetDesc (&surface_description);
+    backbuffer -> GetDesc (&surface_description);
 
-  pool = D3DPOOL_SYSTEMMEM;
+    pool = D3DPOOL_SYSTEMMEM;
     hr = _d3d_device->CreateOffscreenPlainSurface(
-          surface_description.Width,
-          surface_description.Height,
-          surface_description.Format,
-          pool,
-          &temp_surface,
-          NULL);
+                                                  surface_description.Width,
+                                                  surface_description.Height,
+                                                  surface_description.Format,
+                                                  pool,
+                                                  &temp_surface,
+                                                  NULL);
     if (FAILED(hr)) {
       dxgsg9_cat.error()
-  << "CreateImageSurface failed in copy_pixel_buffer()"
-  << D3DERRORSTRING(hr);
+        << "CreateImageSurface failed in copy_pixel_buffer()"
+        << D3DERRORSTRING(hr);
       backbuffer->Release();
       return false;
     }
 
     // Now we must copy from the backbuffer to our temporary surface.
 
-//  DX8 VERSION  hr = _d3d_device->CopyRects(backbuffer, &rect, 1, temp_surface, NULL);
     hr = _d3d_device -> GetRenderTargetData (backbuffer, temp_surface);
 
     if (FAILED(hr)) {
@@ -2335,7 +2291,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
       return false;
     }
 
-    copy_inverted = true;
+    //    copy_inverted = true;
 
     RELEASE(backbuffer, dxgsg9, "backbuffer", RELEASE_ONCE);
 
@@ -2365,20 +2321,20 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
     hr = _d3d_device->CreateOffscreenPlainSurface(w, h, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &temp_surface, NULL);
     if (FAILED(hr)) {
       dxgsg9_cat.error()
-  << "CreateImageSurface failed in copy_pixel_buffer()"
-  << D3DERRORSTRING(hr);
+        << "CreateImageSurface failed in copy_pixel_buffer()"
+        << D3DERRORSTRING(hr);
       return false;
     }
 
     UINT swap_chain;
 
-/* ***** DX9 swap chain ??? */
-  swap_chain = 0;
+    /* ***** DX9 swap chain ??? */
+    swap_chain = 0;
     hr = _d3d_device->GetFrontBufferData(swap_chain,temp_surface);
 
     if (hr == D3DERR_DEVICELOST) {
       dxgsg9_cat.error()
-  << "copy_pixel_buffer failed: device lost\n";
+        << "copy_pixel_buffer failed: device lost\n";
       temp_surface->Release();
       return false;
     }
@@ -2394,8 +2350,9 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
     return false;
   }
 
+  copy_inverted = false;
   DXTextureContext9::d3d_surface_to_texture(rect, temp_surface,
-              copy_inverted, tex, z);
+                                            copy_inverted, tex, z);
 
   RELEASE(temp_surface, dxgsg9, "temp_surface", RELEASE_ONCE);
 

+ 1 - 1
panda/src/dxgsg9/dxGraphicsStateGuardian9.h

@@ -134,7 +134,7 @@ public:
                            bool force);
   virtual void end_draw_primitives();
 
-  virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
+  virtual bool framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
                                            const RenderBuffer &rb);
   virtual bool framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
                                        const RenderBuffer &rb);

+ 12 - 8
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -290,6 +290,7 @@ CLP(GraphicsStateGuardian)::
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 reset() {
+  cerr << "begin reset\n";
   free_pointers();
   GraphicsStateGuardian::reset();
 
@@ -1331,6 +1332,7 @@ reset() {
   // Now that the GSG has been initialized, make it available for
   // optimizations.
   add_gsg(this);
+  cerr << "end reset()\n";
 }
 
 
@@ -3428,10 +3430,10 @@ make_geom_munger(const RenderState *state, Thread *current_thread) {
 //               If z > -1, it is the cube map index into which to
 //               copy.
 ////////////////////////////////////////////////////////////////////
-void CLP(GraphicsStateGuardian)::
+bool CLP(GraphicsStateGuardian)::
 framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
                             const RenderBuffer &rb) {
-  nassertv(tex != NULL && dr != NULL);
+  nassertr(tex != NULL && dr != NULL, false);
   set_read_buffer(rb._buffer_type);
   
   int xo, yo, w, h;
@@ -3447,17 +3449,17 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   // Sanity check everything.
   if (z >= 0) {
     if (!_supports_cube_map) {
-      return;
+      return false;
     }
-    nassertv(z < 6);
-    nassertv(tex->get_texture_type() == Texture::TT_cube_map);
+    nassertr(z < 6, false);
+    nassertr(tex->get_texture_type() == Texture::TT_cube_map, false);
     if ((w != tex->get_x_size()) ||
         (h != tex->get_y_size()) ||
         (w != h)) {
-      return;
+      return false;
     }
   } else {
-    nassertv(tex->get_texture_type() == Texture::TT_2d_texture);
+    nassertr(tex->get_texture_type() == Texture::TT_2d_texture, false);
   }
 
   // Match framebuffer format if necessary.
@@ -3479,7 +3481,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   }
 
   TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
-  nassertv(tc != (TextureContext *)NULL);
+  nassertr(tc != (TextureContext *)NULL, false);
   apply_texture(tc);
 
   if (z >= 0) {
@@ -3497,6 +3499,8 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   // Force reload of texture state, since we've just monkeyed with it.
   _state_rs = 0;
   _state._texture = 0;
+
+  return true;
 }
 
 

+ 1 - 1
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -181,7 +181,7 @@ public:
 
   virtual void clear(DrawableRegion *region);
   
-  virtual void framebuffer_copy_to_texture
+  virtual bool framebuffer_copy_to_texture
     (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);
   virtual bool framebuffer_copy_to_ram
     (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);

+ 1 - 1
panda/src/gsgbase/graphicsStateGuardianBase.h

@@ -191,7 +191,7 @@ public:
   virtual bool draw_points(const GeomPrimitivePipelineReader *reader, bool force)=0;
   virtual void end_draw_primitives()=0;
 
-  virtual void framebuffer_copy_to_texture
+  virtual bool framebuffer_copy_to_texture
   (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0;
   virtual bool framebuffer_copy_to_ram
   (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0;

+ 1 - 0
panda/src/mesadisplay/osMesaGraphicsStateGuardian.cxx

@@ -36,6 +36,7 @@ OSMesaGraphicsStateGuardian(GraphicsPipe *pipe,
 
   // OSMesa is never hardware-accelerated.
   _is_hardware = false;
+  cerr << "constructed " << this << "\n";
 }
 
 ////////////////////////////////////////////////////////////////////

+ 6 - 4
panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx

@@ -1245,10 +1245,10 @@ end_draw_primitives() {
 //               If z > -1, it is the cube map index into which to
 //               copy.
 ////////////////////////////////////////////////////////////////////
-void TinyGraphicsStateGuardian::
+bool TinyGraphicsStateGuardian::
 framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
                             const RenderBuffer &rb) {
-  nassertv(tex != NULL && dr != NULL);
+  nassertr(tex != NULL && dr != NULL, false);
   
   int xo, yo, w, h;
   dr->get_region_pixels_i(xo, yo, w, h);
@@ -1256,12 +1256,12 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   tex->setup_2d_texture(w, h, Texture::T_unsigned_byte, Texture::F_rgba);
 
   TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
-  nassertv(tc != (TextureContext *)NULL);
+  nassertr(tc != (TextureContext *)NULL, false);
   TinyTextureContext *gtc = DCAST(TinyTextureContext, tc);
 
   GLTexture *gltex = &gtc->_gltex;
   if (!setup_gltex(gltex, tex->get_x_size(), tex->get_y_size(), 1)) {
-    return;
+    return false;
   }
 
   PIXEL *ip = gltex->levels[0].pixmap + gltex->xsize * gltex->ysize;
@@ -1275,6 +1275,8 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   gtc->update_data_size_bytes(gltex->xsize * gltex->ysize * 4);
   gtc->mark_loaded();
   gtc->enqueue_lru(&_textures_lru);
+
+  return true;
 }
 
 

+ 1 - 1
panda/src/tinydisplay/tinyGraphicsStateGuardian.h

@@ -76,7 +76,7 @@ public:
                            bool force);
   virtual void end_draw_primitives();
 
-  virtual void framebuffer_copy_to_texture
+  virtual bool framebuffer_copy_to_texture
   (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);
   virtual bool framebuffer_copy_to_ram
   (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);