Browse Source

Add depth buffer sharing.

aignacio_sf 18 years ago
parent
commit
6dfe4ab030

+ 21 - 0
panda/src/display/graphicsOutput.cxx

@@ -1218,3 +1218,24 @@ operator << (ostream &out, GraphicsOutput::FrameMode fm) {
   return out << "(**invalid GraphicsOutput::FrameMode(" << (int)fm << ")**)";
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsOutput::share_depth_buffer
+//       Access: Published, Virtual
+//  Description: Will attempt to use the depth buffer of the input
+//               graphics_output. The buffer sizes must be exactly 
+//               the same. 
+////////////////////////////////////////////////////////////////////
+bool GraphicsOutput::
+share_depth_buffer(GraphicsOutput *graphics_output) {
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsOutput::unshare_depth_buffer
+//       Access: Published, Virtual
+//  Description: Discontinue sharing the depth buffer.
+////////////////////////////////////////////////////////////////////
+void GraphicsOutput::
+unshare_depth_buffer() {
+
+}

+ 3 - 0
panda/src/display/graphicsOutput.h

@@ -194,6 +194,9 @@ PUBLISHED:
 
   NodePath get_texture_card();
 
+  virtual bool share_depth_buffer(GraphicsOutput *graphics_output);
+  virtual void unshare_depth_buffer();
+
 public:
   // These are not intended to be called directly by the user.
   INLINE bool flip_ready() const;

+ 175 - 20
panda/src/dxgsg9/wdxGraphicsBuffer9.cxx

@@ -54,6 +54,9 @@ wdxGraphicsBuffer9(GraphicsPipe *pipe,
   // same buffer we draw into.
   _screenshot_buffer_type = _draw_buffer_type;
 
+  _shared_depth_buffer = 0;
+  _debug = 0;
+  
   if (_gsg) {
     // save to GSG list to handle device lost issues
     DXGraphicsStateGuardian9 *dxgsg;
@@ -79,6 +82,29 @@ wdxGraphicsBuffer9::
     dxgsg -> _graphics_buffer_list.remove(this);
   }
 
+  // unshare shared depth buffer if any
+  this -> unshare_depth_buffer();  
+
+  // unshare all buffers that are sharing this object's depth buffer
+  {
+    wdxGraphicsBuffer9 *graphics_buffer;
+    list <wdxGraphicsBuffer9 *>::iterator graphics_buffer_iterator;
+
+    graphics_buffer_iterator = _shared_depth_buffer_list.begin( );
+    while (graphics_buffer_iterator != _shared_depth_buffer_list.end( )) {
+      graphics_buffer = (*graphics_buffer_iterator);
+      if (graphics_buffer) {      
+        // this call removes the entry from the list
+        graphics_buffer -> unshare_depth_buffer();
+      }      
+      graphics_buffer_iterator = _shared_depth_buffer_list.begin( );
+    }
+  }  
+
+  if (_debug) {
+    printf ("wdxGraphicsBuffer9 destructor \n");
+  }
+  
   this -> close_buffer ( );
 }
 
@@ -147,7 +173,7 @@ end_frame(FrameMode mode, Thread *current_thread) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: wglGraphicsStateGuardian::save_bitplanes
+//     Function: wdxGraphicsBuffer9::save_bitplanes
 //       Access: Public
 //  Description: After rendering, d3d_device will need to be restored
 //               to its initial state.  This function saves the state.
@@ -170,7 +196,7 @@ save_bitplanes() {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: wglGraphicsStateGuardian::restore_bitplanes
+//     Function: wdxGraphicsBuffer9::restore_bitplanes
 //       Access: Public
 //  Description: After rendering, d3d_device will need to be restored
 //               to its initial state.  This function restores the state.
@@ -200,14 +226,13 @@ restore_bitplanes() {
 
 
 ////////////////////////////////////////////////////////////////////
-//     Function: wglGraphicsStateGuardian::rebuild_bitplanes
+//     Function: wdxGraphicsBuffer9::rebuild_bitplanes
 //       Access: Public
 //  Description: If necessary, reallocates (or allocates) the
 //               bitplanes for the buffer.
 ////////////////////////////////////////////////////////////////////
 bool wdxGraphicsBuffer9::
 rebuild_bitplanes() {
-
   HRESULT hr;
   Texture *color_tex = 0;
   Texture *depth_tex = 0;
@@ -300,30 +325,51 @@ rebuild_bitplanes() {
     }
   }
 
+  bool release_depth;
+  
+  release_depth = true;  
   if (depth_tex_index < 0) {
-    // Maintain the backing depth surface.
-    if ((_depth_backing_store)&&
-        ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
-      _depth_backing_store->Release();
-      _depth_backing_store = NULL;
+    if (_shared_depth_buffer) {
+      if (_shared_depth_buffer -> _depth_backing_store) {
+        if (_debug) {
+          printf ("SHARE DEPTH BUFFER\n");
+        }
+        depth_surf = _shared_depth_buffer -> _depth_backing_store;
+        release_depth = false;
+      }
     }
-    if (!_depth_backing_store) {
-      hr = _dxgsg -> _d3d_device ->
-        CreateDepthStencilSurface (bitplane_x, bitplane_y, _saved_depth_desc.Format,
-                                   _saved_depth_desc.MultiSampleType, _saved_depth_desc.MultiSampleQuality,
-                                   false, &_depth_backing_store, NULL);
-      if (!SUCCEEDED(hr)) {
-        dxgsg9_cat.error ( ) << "CreateDepthStencilSurface " << D3DERRORSTRING(hr) FL;
+    if (depth_surf == 0) {
+      // Maintain the backing depth surface.
+      if ((_depth_backing_store)&&
+          ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
+        _depth_backing_store->Release();
+        _depth_backing_store = NULL;
+      }
+      if (!_depth_backing_store) {
+        hr = _dxgsg -> _d3d_device ->
+          CreateDepthStencilSurface (bitplane_x, bitplane_y, _saved_depth_desc.Format,
+                                     _saved_depth_desc.MultiSampleType, _saved_depth_desc.MultiSampleQuality,
+                                     false, &_depth_backing_store, NULL);
+        if (!SUCCEEDED(hr)) {
+          dxgsg9_cat.error ( ) << "CreateDepthStencilSurface " << D3DERRORSTRING(hr) FL;
+        }
       }
+      depth_surf = _depth_backing_store;
     }
-    depth_surf = _depth_backing_store;
   } else {
     // Maintain the depth texture.
     if (_depth_backing_store) {
       _depth_backing_store->Release();
       _depth_backing_store = NULL;
     }
-    depth_tex = get_texture(depth_tex_index);
+
+    if (_shared_depth_buffer) {      
+      depth_tex = _shared_depth_buffer -> get_texture(depth_tex_index);
+    }
+    if (depth_tex == 0) {        
+      depth_tex = get_texture(depth_tex_index);
+    }
+
     depth_tex->set_x_size(bitplane_x);
     depth_tex->set_y_size(bitplane_y);
     depth_tex->set_format(Texture::F_depth_stencil);
@@ -374,9 +420,13 @@ rebuild_bitplanes() {
   if ((color_surf != 0)&&(color_surf != _color_backing_store)) {
     color_surf->Release();
   }
-  if ((depth_surf != 0)&&(depth_surf != _depth_backing_store)) {
-    depth_surf->Release();
+
+  if (release_depth) {
+    if ((depth_surf != 0)&&(depth_surf != _depth_backing_store)) {
+      depth_surf->Release();
+    }
   }
+  
   return true;
 }
 
@@ -558,3 +608,108 @@ process_1_event() {
   // Call window_proc
   DispatchMessage(&msg);
 }
+
+
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::share_depth_buffer
+//       Access: Published 
+//  Description: Will attempt to use the depth buffer of the input
+//               graphics_output. The buffer sizes must be exactly 
+//               the same. 
+////////////////////////////////////////////////////////////////////
+bool wdxGraphicsBuffer9::
+share_depth_buffer(GraphicsOutput *graphics_output) {
+
+  bool state;
+  wdxGraphicsBuffer9 *input_graphics_output;
+  
+  state = false;
+  input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output);
+  if (this != input_graphics_output && input_graphics_output) {
+
+    state = true;
+    this -> unshare_depth_buffer();
+
+    if (_debug) {
+      printf ("share_depth_buffer\n");
+    }
+    
+    // check buffer sizes
+    if (this -> get_x_size() != input_graphics_output -> get_x_size()) {    
+      if (_debug) {
+        printf ("ERROR: share_depth_buffer: non matching width \n");
+      }
+      state = false;    
+    }
+
+    if (this -> get_y_size() != input_graphics_output -> get_y_size()) {     
+      if (_debug) {
+        printf ("ERROR: share_depth_buffer: non matching height \n");
+      }
+      state = false;    
+    }
+
+    if (state) {    
+      // let the input GraphicsOutput know that there is an object 
+      // sharing its depth buffer      
+      input_graphics_output -> register_shared_depth_buffer(this);
+      _shared_depth_buffer = input_graphics_output;
+      state = true;
+    }
+  }
+  
+  return state;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::unshare_depth_buffer
+//       Access: Published 
+//  Description: Discontinue sharing the depth buffer.
+////////////////////////////////////////////////////////////////////
+void wdxGraphicsBuffer9::
+unshare_depth_buffer() {
+  if (_shared_depth_buffer) {
+    if (_debug) {
+      printf ("wdxGraphicsBuffer9 unshare_depth_buffer \n");
+    }
+    
+    // let the GraphicsOutput know that this object is no longer
+    // sharing its depth buffer
+    _shared_depth_buffer -> unregister_shared_depth_buffer(this);  
+    _shared_depth_buffer = 0;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::register_shared_depth_buffer
+//       Access: Public
+//  Description: Register/save who is sharing the depth buffer.
+////////////////////////////////////////////////////////////////////
+void wdxGraphicsBuffer9::
+register_shared_depth_buffer(GraphicsOutput *graphics_output) {
+  wdxGraphicsBuffer9 *input_graphics_output;
+  
+  input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output);
+  if (input_graphics_output) {
+    // add to list  
+    _shared_depth_buffer_list.push_back(input_graphics_output);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::unregister_shared_depth_buffer
+//       Access: Public
+//  Description: Unregister who is sharing the depth buffer.
+////////////////////////////////////////////////////////////////////
+void wdxGraphicsBuffer9::
+unregister_shared_depth_buffer(GraphicsOutput *graphics_output) {
+  wdxGraphicsBuffer9 *input_graphics_output;
+  
+  input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output);
+  if (input_graphics_output) {
+    // remove from list  
+    _shared_depth_buffer_list.remove(input_graphics_output);
+  }
+}

+ 10 - 0
panda/src/dxgsg9/wdxGraphicsBuffer9.h

@@ -51,6 +51,12 @@ public:
   virtual void select_cube_map(int cube_map_index);
   virtual void process_events();
 
+  virtual bool share_depth_buffer(GraphicsOutput *graphics_output);
+  virtual void unshare_depth_buffer();
+
+  void register_shared_depth_buffer(GraphicsOutput *graphics_output);
+  void unregister_shared_depth_buffer(GraphicsOutput *graphics_output);
+
 protected:
   virtual void close_buffer();
   virtual bool open_buffer();
@@ -72,6 +78,9 @@ private:
   int _backing_sizex;
   int _backing_sizey;
 
+  wdxGraphicsBuffer9 *_shared_depth_buffer;
+  list <wdxGraphicsBuffer9 *> _shared_depth_buffer_list;
+
 public:
   static TypeHandle get_class_type() {
     return _type_handle;
@@ -87,6 +96,7 @@ public:
   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
 
 private:
+  bool _debug;
   static TypeHandle _type_handle;
 
   friend class DXGraphicsStateGuardian9;

+ 130 - 4
panda/src/glstuff/glGraphicsBuffer_src.cxx

@@ -46,6 +46,8 @@ CLP(GraphicsBuffer)(GraphicsPipe *pipe,
     _rb[i] = 0;
     _tex[i] = 0;
   }
+
+  _shared_depth_buffer = 0;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -55,6 +57,24 @@ CLP(GraphicsBuffer)(GraphicsPipe *pipe,
 ////////////////////////////////////////////////////////////////////
 CLP(GraphicsBuffer)::
 ~CLP(GraphicsBuffer)() {
+  // unshare shared depth buffer if any
+  this -> unshare_depth_buffer();  
+
+  // unshare all buffers that are sharing this object's depth buffer
+  {
+    CLP(GraphicsBuffer) *graphics_buffer;
+    list <CLP(GraphicsBuffer) *>::iterator graphics_buffer_iterator;
+
+    graphics_buffer_iterator = _shared_depth_buffer_list.begin( );
+    while (graphics_buffer_iterator != _shared_depth_buffer_list.end( )) {
+      graphics_buffer = (*graphics_buffer_iterator);
+      if (graphics_buffer) {      
+        // this call removes the entry from the list
+        graphics_buffer -> unshare_depth_buffer();
+      }      
+      graphics_buffer_iterator = _shared_depth_buffer_list.begin( );
+    }
+  }  
 }
  
 ////////////////////////////////////////////////////////////////////
@@ -336,7 +356,7 @@ bind_slot(bool rb_resize, Texture **attach, RenderTexturePlane slot, GLenum atta
     
     // If a renderbuffer is already attached to the slot, and it's
     // the right size, then no update of this slot is needed.
-    if ((_rb[slot] != 0)&&(!rb_resize)) {
+    if (_shared_depth_buffer == 0 && (_rb[slot] != 0)&&(!rb_resize)) {
       return;
     }
     
@@ -352,16 +372,33 @@ bind_slot(bool rb_resize, Texture **attach, RenderTexturePlane slot, GLenum atta
         glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT,
                                       _rb_size_x, _rb_size_y);
         glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
+
+        GLuint rb;
+
+        rb = _rb[slot];
+        if (_shared_depth_buffer) {
+          rb = _shared_depth_buffer -> _rb[slot];
+        }
+        
         glgsg->_glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
-                                          GL_RENDERBUFFER_EXT, _rb[slot]);
+                                          GL_RENDERBUFFER_EXT, rb);
+
         glgsg->_glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
-                                          GL_RENDERBUFFER_EXT, _rb[slot]);
+                                          GL_RENDERBUFFER_EXT, rb);
       } else {
         glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
                                       _rb_size_x, _rb_size_y);
         glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
+
+        GLuint rb;
+
+        rb = _rb[slot];
+        if (_shared_depth_buffer) {
+          rb = _shared_depth_buffer -> _rb[slot];
+        }
+
         glgsg->_glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
-                                          GL_RENDERBUFFER_EXT, _rb[slot]);
+                                          GL_RENDERBUFFER_EXT, rb);
       }
     } else {
       glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_RGBA,
@@ -577,3 +614,92 @@ close_buffer() {
   _is_valid = false;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: glGraphicsBuffer::share_depth_buffer
+//       Access: Published 
+//  Description: Will attempt to use the depth buffer of the input
+//               graphics_output. The buffer sizes must be exactly 
+//               the same. 
+////////////////////////////////////////////////////////////////////
+bool CLP(GraphicsBuffer)::
+share_depth_buffer(GraphicsOutput *graphics_output) {
+
+  bool state;
+  CLP(GraphicsBuffer) *input_graphics_output;
+  
+  state = false;
+  input_graphics_output = DCAST (CLP(GraphicsBuffer), graphics_output);
+  if (this != input_graphics_output && input_graphics_output) {
+
+    state = true;
+    this -> unshare_depth_buffer();
+    
+    // check buffer sizes
+    if (this -> get_x_size() != input_graphics_output -> get_x_size()) {    
+      GLCAT.error() << "share_depth_buffer: non matching width \n";
+      state = false;    
+    }
+
+    if (this -> get_y_size() != input_graphics_output -> get_y_size()) {     
+      GLCAT.error() << "share_depth_buffer: non matching height \n";
+      state = false;    
+    }
+
+    if (state) {    
+      // let the input GraphicsOutput know that there is an object 
+      // sharing its depth buffer      
+      input_graphics_output -> register_shared_depth_buffer(this);
+      _shared_depth_buffer = input_graphics_output;
+      state = true;
+    }
+  }
+  
+  return state;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: glGraphicsBuffer::unshare_depth_buffer
+//       Access: Published 
+//  Description: Discontinue sharing the depth buffer.
+////////////////////////////////////////////////////////////////////
+void CLP(GraphicsBuffer)::
+unshare_depth_buffer() {
+  if (_shared_depth_buffer) {
+    // let the GraphicsOutput know that this object is no longer
+    // sharing its depth buffer
+    _shared_depth_buffer -> unregister_shared_depth_buffer(this);  
+    _shared_depth_buffer = 0;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: glGraphicsBuffer::register_shared_depth_buffer
+//       Access: Public
+//  Description: Register/save who is sharing the depth buffer.
+////////////////////////////////////////////////////////////////////
+void CLP(GraphicsBuffer)::
+register_shared_depth_buffer(GraphicsOutput *graphics_output) {
+  CLP(GraphicsBuffer) *input_graphics_output;
+  
+  input_graphics_output = DCAST (CLP(GraphicsBuffer), graphics_output);
+  if (input_graphics_output) {
+    // add to list  
+    _shared_depth_buffer_list.push_back(input_graphics_output);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: glGraphicsBuffer::unregister_shared_depth_buffer
+//       Access: Public
+//  Description: Unregister who is sharing the depth buffer.
+////////////////////////////////////////////////////////////////////
+void CLP(GraphicsBuffer)::
+unregister_shared_depth_buffer(GraphicsOutput *graphics_output) {
+  CLP(GraphicsBuffer) *input_graphics_output;
+  
+  input_graphics_output = DCAST (CLP(GraphicsBuffer), graphics_output);
+  if (input_graphics_output) {
+    // remove from list  
+    _shared_depth_buffer_list.remove(input_graphics_output);
+  }
+}

+ 9 - 0
panda/src/glstuff/glGraphicsBuffer_src.h

@@ -70,6 +70,12 @@ public:
 
   virtual void select_cube_map(int cube_map_index);
 
+  virtual bool share_depth_buffer(GraphicsOutput *graphics_output);
+  virtual void unshare_depth_buffer();
+
+  void register_shared_depth_buffer(GraphicsOutput *graphics_output);
+  void unregister_shared_depth_buffer(GraphicsOutput *graphics_output);
+
 protected:
   virtual void close_buffer();
   virtual bool open_buffer();
@@ -89,6 +95,9 @@ private:
   PT(Texture) _tex[RTP_COUNT];
   GLuint      _rb[RTP_COUNT];
   GLenum      _attach_point[RTP_COUNT];
+
+  CLP(GraphicsBuffer) *_shared_depth_buffer;
+  list <CLP(GraphicsBuffer) *> _shared_depth_buffer_list;
   
 public:
   static TypeHandle get_class_type() {