Ver Fonte

Repairs to DX buffers

Josh Yelon há 19 anos atrás
pai
commit
40db93b374

+ 4 - 2
panda/src/display/graphicsBuffer.cxx

@@ -119,8 +119,10 @@ process_events() {
     return;
 
   case OR_open:
-    open_buffer();
-    set_inverted(_gsg->get_copy_texture_inverted());
+    if (open_buffer()) {
+      _is_valid = true;
+      set_inverted(_gsg->get_copy_texture_inverted());
+    }
     break;
 
   case OR_close:

+ 243 - 272
panda/src/dxgsg8/wdxGraphicsBuffer8.cxx

@@ -51,13 +51,12 @@ wdxGraphicsBuffer8(GraphicsPipe *pipe,
 {
   // initialize all class members
   _cube_map_index = -1;
-  _back_buffer = NULL;
-  _z_stencil_buffer = NULL;
-  _direct_3d_surface = NULL;
-  _dx_texture_context8 = NULL;
-  _new_z_stencil_surface = NULL;
+  _saved_color_buffer = NULL;
+  _saved_depth_buffer = NULL;
+  _color_backing_store = NULL;
+  _depth_backing_store = NULL;
 
-// is this correct ???
+  // is this correct ???
   // Since the pbuffer never gets flipped, we get screenshots from the
   // same buffer we draw into.
   _screenshot_buffer_type = _draw_buffer_type;
@@ -89,9 +88,18 @@ begin_frame(FrameMode mode, Thread *current_thread) {
   if (_gsg == (GraphicsStateGuardian *)NULL) {
     return false;
   }
-
+  if (_dxgsg -> _d3d_device == 0) {
+    return false;
+  }
+  
   if (mode == FM_render) {
-    begin_render_texture();
+    if (!save_bitplanes()) {
+      return false;
+    }
+    if (!rebuild_bitplanes()) {
+      restore_bitplanes();
+      return false;
+    }
     clear_cube_map_selection();
   }
 
@@ -113,7 +121,6 @@ end_frame(FrameMode mode, Thread *current_thread) {
   nassertv(_gsg != (GraphicsStateGuardian *)NULL);
 
   if (mode == FM_render) {
-    end_render_texture();
     copy_to_textures();
   }
 
@@ -125,138 +132,232 @@ end_frame(FrameMode mode, Thread *current_thread) {
       prepare_for_deletion();
     }
     clear_cube_map_selection();
+    restore_bitplanes();
   }
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: wglGraphicsStateGuardian::begin_render_texture
+//     Function: wglGraphicsStateGuardian::save_bitplanes
 //       Access: Public
-//  Description: If the GraphicsOutput supports direct render-to-texture,
-//               and if any setup needs to be done during begin_frame,
-//               then the setup code should go here.  Any textures that
-//               can not be rendered to directly should be reflagged
-//               as RTM_copy_texture.
+//  Description: After rendering, d3d_device will need to be restored 
+//               to its initial state.  This function saves the state.
 ////////////////////////////////////////////////////////////////////
-void wdxGraphicsBuffer8::
-begin_render_texture() {
-
-  if (_gsg != (GraphicsStateGuardian *)NULL) {
-
-    DXGraphicsStateGuardian8 *dxgsg;
-    DCAST_INTO_V(dxgsg, _gsg);
+bool wdxGraphicsBuffer8::
+save_bitplanes() {
+  HRESULT hr;
 
-    HRESULT hr;
-    bool state;
+  hr = _dxgsg -> _d3d_device -> GetRenderTarget (&_saved_color_buffer);
+  if (!SUCCEEDED (hr)) {
+    dxgsg8_cat.error ( ) << "GetRenderTarget " << D3DERRORSTRING(hr) FL;
+    return false;
+  }
+  hr = _saved_color_buffer -> GetDesc (&_saved_color_desc);
+  if (!SUCCEEDED (hr)) {
+    dxgsg8_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL;
+    return false;
+  }
+  hr = _dxgsg -> _d3d_device -> GetDepthStencilSurface (&_saved_depth_buffer);
+  if (!SUCCEEDED (hr)) {
+    dxgsg8_cat.error ( ) << "GetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
+    return false;
+  }
+  hr = _saved_depth_buffer -> GetDesc (&_saved_depth_desc);
+  if (!SUCCEEDED (hr)) {
+    dxgsg8_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL;
+    return false;
+  }
+  return true;
+}
 
-    state = false;
+////////////////////////////////////////////////////////////////////
+//     Function: wglGraphicsStateGuardian::restore_bitplanes
+//       Access: Public
+//  Description: After rendering, d3d_device will need to be restored 
+//               to its initial state.  This function restores the state.
+////////////////////////////////////////////////////////////////////
+void wdxGraphicsBuffer8::
+restore_bitplanes() {
+  DXGraphicsStateGuardian8 *dxgsg;
+  DCAST_INTO_V(dxgsg, _gsg);
+
+  HRESULT hr;
+  
+  hr = dxgsg -> _d3d_device ->
+    SetRenderTarget (_saved_color_buffer, _saved_depth_buffer);
+  
+  if (!SUCCEEDED (hr)) {
+    dxgsg8_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
+  }
+  
+  _saved_color_buffer->Release();
+  _saved_depth_buffer->Release();
+  _saved_color_buffer = NULL;
+  _saved_depth_buffer = NULL;
+}
 
-    if (dxgsg -> _d3d_device) {
-      Texture *tex = get_texture(0);
-      tex->set_render_to_texture(true);
-      TextureContext *tc = tex->prepare_now(_gsg->get_prepared_objects(), _gsg);
 
-      _dx_texture_context8 = DCAST (DXTextureContext8, tc);
+////////////////////////////////////////////////////////////////////
+//     Function: wglGraphicsStateGuardian::rebuild_bitplanes
+//       Access: Public
+//  Description: If necessary, reallocates (or allocates) the 
+//               bitplanes for the buffer.
+////////////////////////////////////////////////////////////////////
+bool wdxGraphicsBuffer8::
+rebuild_bitplanes() {
+
+  HRESULT hr;
+  Texture *color_tex = 0;
+  Texture *depth_tex = 0;
+  DXTextureContext8 *color_ctx = 0;
+  DXTextureContext8 *depth_ctx = 0;
+  IDirect3DTexture8 *color_d3d_tex = 0;
+  IDirect3DTexture8 *depth_d3d_tex = 0;
+  IDirect3DCubeTexture8 *color_cube = 0;
+  IDirect3DCubeTexture8 *depth_cube = 0;
+  IDirect3DSurface8 *color_surf = 0;
+  IDirect3DSurface8 *depth_surf = 0;
+
+  // Decide how big the bitplanes should be.
+
+  int bitplane_x = _x_size;
+  int bitplane_y = _y_size;
+  if (!_gsg->get_supports_tex_non_pow2()) {
+    bitplane_x = Texture::up_to_power_2(bitplane_x);
+    bitplane_y = Texture::up_to_power_2(bitplane_y);
+  }
 
-      // save render context
-      hr = dxgsg -> _d3d_device -> GetRenderTarget (&_back_buffer);
-      if (SUCCEEDED (hr)) {
-        hr = dxgsg -> _d3d_device -> GetDepthStencilSurface (&_z_stencil_buffer);
-        if (SUCCEEDED (hr)) {
-          state = true;
-        }
-        else {
-          dxgsg8_cat.error ( ) << "GetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
-        }
+  // Find the color and depth textures.  Either may be present,
+  // or neither.  
+  //
+  // NOTE: Currently, depth-stencil textures are not implemented,
+  // but since it's coming soon, we're structuring for it.
+  
+  int color_tex_index = -1;
+  int depth_tex_index = -1;
+  for (int i=0; i<count_textures(); i++) {
+    if (get_rtm_mode(i) == RTM_bind_or_copy) {
+      if ((get_texture(i)->get_format() != Texture::F_depth_component)&&
+          (get_texture(i)->get_format() != Texture::F_stencil_index)&&
+          (color_tex_index < 0)) {
+        color_tex_index = i;
+      } else {
+        _textures[i]._rtm_mode = RTM_copy_texture;
+      }
+    }
+  }
+  
+
+  if (color_tex_index < 0) {
+    // Maintain the backing color surface.
+    if ((_color_backing_store)&&
+        ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
+      _color_backing_store->Release();
+      _color_backing_store = NULL;
+    }
+    if (!_color_backing_store) {
+      hr = _dxgsg -> _d3d_device ->
+        CreateImageSurface(bitplane_x, bitplane_y, _saved_color_desc.Format, &_color_backing_store);
+      if (!SUCCEEDED(hr)) {
+        dxgsg8_cat.error ( ) << "CreateImageSurface " << D3DERRORSTRING(hr) FL;
       }
-      else {
-        dxgsg8_cat.error ( ) << "GetRenderTarget " << D3DERRORSTRING(hr) FL;
+    }
+    color_surf = _color_backing_store;
+  } else {
+    // Maintain the color texture.
+    if (_color_backing_store) {
+      _color_backing_store->Release();
+      _color_backing_store = NULL;
+    }
+    color_tex = get_texture(color_tex_index);
+    color_tex->set_x_size(bitplane_x);
+    color_tex->set_y_size(bitplane_y);
+    color_tex->set_format(Texture::F_rgba);
+    color_ctx = 
+      DCAST(DXTextureContext8,
+            color_tex->prepare_now(_gsg->get_prepared_objects(), _gsg));
+    if (color_tex->get_texture_type() == Texture::TT_2d_texture) {
+      color_d3d_tex = color_ctx->_d3d_2d_texture;
+      nassertr(color_d3d_tex != 0, false);
+      hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf);
+      if (!SUCCEEDED(hr)) {
+        dxgsg8_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
       }
-
-      // set render context
-      if (state && _dx_texture_context8)
-      {
-        DXTextureContext8 *dx_texture_context8;
-
-        // use saved dx_texture_context8
-        dx_texture_context8 = _dx_texture_context8;
-
-        UINT mipmap_level;
-
-        mipmap_level = 0;
-        _direct_3d_surface = NULL;
-
-        // render to texture 2D
-        IDirect3DTexture8 *direct_3d_texture;
-
-        direct_3d_texture = dx_texture_context8 -> _d3d_2d_texture;
-        if (direct_3d_texture) {
-          hr = direct_3d_texture -> GetSurfaceLevel (mipmap_level, &_direct_3d_surface);
-          if (SUCCEEDED (hr)) {
-            IDirect3DSurface8 *z_stencil_buffer;
-
-            if (this -> _new_z_stencil_surface) {
-              z_stencil_buffer = this -> _new_z_stencil_surface;
-            }
-            else {
-              z_stencil_buffer = _z_stencil_buffer;
-            }
-
-            hr = dxgsg -> _d3d_device -> SetRenderTarget (_direct_3d_surface, z_stencil_buffer);
-            if (SUCCEEDED (hr)) {
-
-            } else {
-              dxgsg8_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
-            }
-          } else {
-            dxgsg8_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
-          }
-        }
+    } else {
+      color_cube = color_ctx->_d3d_cube_texture;
+      nassertr(color_cube != 0, false);
+      hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf);
+      if (!SUCCEEDED(hr)) {
+        dxgsg8_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
       }
     }
   }
-}
 
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsOutput::end_render_texture
-//       Access: Public
-//  Description: If the GraphicsOutput supports direct render-to-texture,
-//               and if any setup needs to be done during end_frame,
-//               then the setup code should go here.  Any textures that
-//               could not be rendered to directly should be reflagged
-//               as RTM_copy_texture.
-////////////////////////////////////////////////////////////////////
-void wdxGraphicsBuffer8::
-end_render_texture() {
-
-  if (_gsg != (GraphicsStateGuardian *)NULL) {
-
-    DXGraphicsStateGuardian8 *dxgsg;
-    DCAST_INTO_V(dxgsg, _gsg);
-
-    if (dxgsg -> _d3d_device) {
-      // restore render context
-      HRESULT hr;
-
-      if (_back_buffer) {
-        hr = dxgsg -> _d3d_device -> SetRenderTarget (_back_buffer,
-          _z_stencil_buffer);
-        if (SUCCEEDED (hr)) {
-          _back_buffer -> Release ( );
-        } else {
-          dxgsg8_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
-        }
-        _back_buffer = NULL;
+  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 (!_depth_backing_store) {
+      hr = _dxgsg -> _d3d_device ->
+        CreateDepthStencilSurface (bitplane_x, bitplane_y, _saved_depth_desc.Format, 
+                                   _saved_depth_desc.MultiSampleType, &_depth_backing_store);
+      if (!SUCCEEDED(hr)) {
+        dxgsg8_cat.error ( ) << "CreateDepthStencilSurface " << D3DERRORSTRING(hr) FL;
       }
-      if (_z_stencil_buffer) {
-        _z_stencil_buffer -> Release ( );
-        _z_stencil_buffer = NULL;
+    }
+    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);
+    depth_tex->set_x_size(bitplane_x);
+    depth_tex->set_y_size(bitplane_y);
+    depth_tex->set_format(Texture::F_depth_component); // Should say depth_stencil
+    depth_ctx = 
+      DCAST(DXTextureContext8,
+            depth_tex->prepare_now(_gsg->get_prepared_objects(), _gsg));
+    if (depth_tex->get_texture_type() == Texture::TT_2d_texture) {
+      depth_d3d_tex = depth_ctx->_d3d_2d_texture;
+      nassertr(depth_d3d_tex != 0, false);
+      hr = color_d3d_tex -> GetSurfaceLevel(0, &depth_surf);
+      if (!SUCCEEDED(hr)) {
+        dxgsg8_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
       }
-      if (_direct_3d_surface) {
-        _direct_3d_surface -> Release ( );
-        _direct_3d_surface = NULL;
+    } else {
+      depth_cube = depth_ctx->_d3d_cube_texture;
+      nassertr(depth_cube != 0, false);
+      hr = depth_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &depth_surf);
+      if (!SUCCEEDED(hr)) {
+        dxgsg8_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
       }
     }
   }
+
+  _backing_sizex = bitplane_x;
+  _backing_sizey = bitplane_y;
+
+  // Load up the bitplanes.
+  
+  hr = _dxgsg -> _d3d_device -> SetRenderTarget (color_surf, depth_surf);
+  if (!SUCCEEDED (hr)) {
+    dxgsg8_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
+  }
+  
+  // Decrement the reference counts on these surfaces. The refcounts
+  // were incremented earlier when we called GetSurfaceLevel.
+
+  if ((color_surf != 0)&&(color_surf != _color_backing_store)) {
+    color_surf->Release();
+  }
+  if ((depth_surf != 0)&&(depth_surf != _depth_backing_store)) {
+    depth_surf->Release();
+  }
+  return true;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -270,63 +371,7 @@ end_render_texture() {
 ////////////////////////////////////////////////////////////////////
 void wdxGraphicsBuffer8::
 select_cube_map(int cube_map_index) {
-
-  if (_gsg != (GraphicsStateGuardian *)NULL) {
-
-    DXGraphicsStateGuardian8 *dxgsg;
-    DCAST_INTO_V(dxgsg, _gsg);
-
-    _cube_map_index = cube_map_index;
-
-    HRESULT hr;
-    UINT mipmap_level;
-    int render_target_index;
-    DXTextureContext8 *dx_texture_context8;
-
-    mipmap_level = 0;
-    render_target_index = 0;
-    dx_texture_context8 = _dx_texture_context8;
-
-    if (_direct_3d_surface) {
-        _direct_3d_surface -> Release ( );
-        _direct_3d_surface = NULL;
-    }
-
-    if (dxgsg -> _d3d_device) {
-
-      // render to cubemap face
-      IDirect3DCubeTexture8 *direct_3d_cube_texture;
-
-      direct_3d_cube_texture = dx_texture_context8 -> _d3d_cube_texture;
-      if (direct_3d_cube_texture) {
-        if (_cube_map_index >= 0 && _cube_map_index < 6) {
-          hr = direct_3d_cube_texture -> GetCubeMapSurface (
-            (D3DCUBEMAP_FACES) _cube_map_index, mipmap_level, &_direct_3d_surface);
-          if (SUCCEEDED (hr)) {
-            IDirect3DSurface8 *z_stencil_buffer;
-
-            if (this -> _new_z_stencil_surface) {
-              z_stencil_buffer = this -> _new_z_stencil_surface;
-            }
-            else {
-              z_stencil_buffer = _z_stencil_buffer;
-            }
-
-            hr = dxgsg -> _d3d_device -> SetRenderTarget (_direct_3d_surface, z_stencil_buffer);
-            if (SUCCEEDED (hr)) {
-
-            } else {
-              dxgsg8_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
-            }
-          } else {
-            dxgsg8_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
-          }
-        } else {
-          dxgsg8_cat.error ( ) << "Invalid Cube Map Face Index " << _cube_map_index FL;
-        }
-      }
-    }
-  }
+  _cube_map_index = cube_map_index;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -363,23 +408,20 @@ void wdxGraphicsBuffer8::
 close_buffer() {
 
   if (_gsg != (GraphicsStateGuardian *)NULL) {
-    DXGraphicsStateGuardian8 *dxgsg;
-    DCAST_INTO_V(dxgsg, _gsg);
-
-    _dx_texture_context8 = NULL;
-
-    // release new depth stencil buffer if one was created
-    if (this -> _new_z_stencil_surface) {
-      this -> _new_z_stencil_surface -> Release ( );
-      this -> _new_z_stencil_surface = NULL;
-    }
-
     _gsg.clear();
-    _active = false;
+  }
+  
+  if (_color_backing_store) {
+    _color_backing_store->Release();
+    _color_backing_store = NULL;
+  }
+  if (_depth_backing_store) {
+    _depth_backing_store->Release();
+    _depth_backing_store = NULL;
   }
 
+  _active = false;
   _cube_map_index = -1;
-
   _is_valid = false;
 }
 
@@ -392,97 +434,26 @@ close_buffer() {
 ////////////////////////////////////////////////////////////////////
 bool wdxGraphicsBuffer8::
 open_buffer() {
-  bool state;
 
   // GSG creation/initialization.
   if (_gsg == 0) {
     _dxgsg = new DXGraphicsStateGuardian8(_pipe);
     _gsg = _dxgsg;
+  } else {
+    DCAST_INTO_R(_dxgsg, _gsg, false);
   }
-
-  // create texture
-  int tex_index;
-
-  state = false;
-  _is_valid = false;
-
-  // assume tex_index is 0
-  tex_index = 0;
-
-  Texture *tex = get_texture(tex_index);
-
-  // render to texture must be set
-  tex->set_render_to_texture(true);
-
-  TextureContext *tc = tex->prepare_now(_gsg->get_prepared_objects(), _gsg);
-  if (tc != NULL) {
-    HRESULT hr;
-    IDirect3DSurface8 *_depth_stencil_surface;
-
-    _dx_texture_context8 = DCAST (DXTextureContext8, tc);
-
-    // create a depth stencil buffer if needed
-    hr = _dxgsg -> _d3d_device -> GetDepthStencilSurface (&_depth_stencil_surface);
-    if (SUCCEEDED  (hr))
-    {
-      D3DSURFACE_DESC surface_description;
-
-      // get and copy the current depth stencil's parameters for the new buffer
-      hr = _depth_stencil_surface -> GetDesc (&surface_description);
-      if (SUCCEEDED  (hr)) {
-        UINT width;
-        UINT height;
-        D3DFORMAT format;
-        D3DMULTISAMPLE_TYPE multisample_type;
-//        DWORD multisample_quality;
-        BOOL discard;
-
-        width = tex -> get_x_size ( );
-        height = tex -> get_y_size ( );
-
-//        dxgsg8_cat.error ( ) << "-------------RTT SIZE " << "t width " << width << " t height " << height << "\n";
-
-        if (surface_description.Width < width || surface_description.Height < height) {
-          format = surface_description.Format;
-          multisample_type = surface_description.MultiSampleType;
-//          multisample_quality = surface_description.MultiSampleQuality;
-          discard = false;
-
-          hr = _dxgsg -> _d3d_device -> CreateDepthStencilSurface (
-            width, height, format, multisample_type, /* multisample_quality,
-            discard, */ &this -> _new_z_stencil_surface);
-          if (SUCCEEDED  (hr)) {
-
-//            dxgsg8_cat.error ( ) << "-------------CreatedDepthStencilSurface for RTT \n";
-
-            state = true;
-
-          } else {
-            dxgsg8_cat.error ( ) << "CreateDepthStencilSurface " << D3DERRORSTRING(hr) FL;
-          }
-        }
-        else {
-          // no need to create a separate depth stencil buffer since
-          // the current depth stencil buffer size is big enough
-          state = true;
-        }
-      }
-      else {
-        dxgsg8_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL;
-      }
-
-      _depth_stencil_surface -> Release ( );
-    }
-    else {
-      dxgsg8_cat.error ( ) << "GetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
-    }
-
-    if (state) {
-      _is_valid = true;
-    }
+  
+  if (!save_bitplanes()) {
+    return false;
   }
 
-  return state;
+  if (!rebuild_bitplanes()) {
+    restore_bitplanes();
+    return false;
+  }
+  
+  restore_bitplanes();
+  return true;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 11 - 8
panda/src/dxgsg8/wdxGraphicsBuffer8.h

@@ -56,18 +56,21 @@ protected:
   virtual bool open_buffer();
 
 private:
-  void begin_render_texture();
-  void end_render_texture();
+  bool save_bitplanes();
+  bool rebuild_bitplanes();
+  void restore_bitplanes();
   static void process_1_event();
 
   int _cube_map_index;
   DXGraphicsStateGuardian8 *_dxgsg;
-  IDirect3DSurface8 *_back_buffer;
-  IDirect3DSurface8 *_z_stencil_buffer;
-  IDirect3DSurface8 *_direct_3d_surface;
-  DXTextureContext8 *_dx_texture_context8;
-
-  IDirect3DSurface8 *_new_z_stencil_surface;
+  IDirect3DSurface8 *_saved_color_buffer;
+  IDirect3DSurface8 *_saved_depth_buffer;
+  D3DSURFACE_DESC    _saved_color_desc;
+  D3DSURFACE_DESC    _saved_depth_desc;
+  IDirect3DSurface8 *_color_backing_store;
+  IDirect3DSurface8 *_depth_backing_store;
+  int _backing_sizex;
+  int _backing_sizey;
 
 public:
   static TypeHandle get_class_type() {

+ 2 - 0
panda/src/dxgsg8/wdxGraphicsWindow8.cxx

@@ -275,6 +275,8 @@ open_window() {
   if (_gsg == 0) {
     _dxgsg = new DXGraphicsStateGuardian8(_pipe);
     _gsg = _dxgsg;
+  } else {
+    DCAST_INTO_R(_dxgsg, _gsg, false);
   }
   
   if (!choose_device()) {

+ 259 - 315
panda/src/dxgsg9/wdxGraphicsBuffer9.cxx

@@ -1,10 +1,10 @@
-// Filename: wdxGraphicsBuffer9.cxx
+// Filename: wdxGraphicsBuffer8.cxx
 // Created by:  drose (08Feb04)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2006, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2005, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -21,8 +21,11 @@
 #include "dxGraphicsStateGuardian9.h"
 #include "pStatTimer.h"
 
-
 // ISSUES:
+  // render to texure format
+    // can be specified via the DXGraphicsStateGuardian8 member
+    // _render_to_texture_d3d_format  default = D3DFMT_X8R8G8B8
+
   // should check texture creation with CheckDepthStencilMatch
   // support copy from texture to ram?
     // check D3DCAPS2_DYNAMICTEXTURES
@@ -40,19 +43,18 @@ TypeHandle wdxGraphicsBuffer9::_type_handle;
 wdxGraphicsBuffer9::
 wdxGraphicsBuffer9(GraphicsPipe *pipe,
                    const string &name,
-                   const FrameBufferProperties &prop,
+                   const FrameBufferProperties &properties,
                    int x_size, int y_size, int flags,
                    GraphicsStateGuardian *gsg,
                    GraphicsOutput *host):
-  GraphicsBuffer(pipe, name, prop, x_size, y_size, flags, gsg, host)
+  GraphicsBuffer(pipe, name, properties, x_size, y_size, flags, gsg, host)
 {
   // initialize all class members
   _cube_map_index = -1;
-  _back_buffer = NULL;
-  _z_stencil_buffer = NULL;
-  _direct_3d_surface = NULL;
-  _dx_texture_context9 = NULL;
-  _new_z_stencil_surface = NULL;
+  _saved_color_buffer = NULL;
+  _saved_depth_buffer = NULL;
+  _color_backing_store = NULL;
+  _depth_backing_store = NULL;
 
   // is this correct ???
   // Since the pbuffer never gets flipped, we get screenshots from the
@@ -81,15 +83,23 @@ wdxGraphicsBuffer9::
 ////////////////////////////////////////////////////////////////////
 bool wdxGraphicsBuffer9::
 begin_frame(FrameMode mode, Thread *current_thread) {
-  DBG_S dxgsg9_cat.debug ( ) << "wdxGraphicsBuffer9::begin_frame\n"; DBG_E
 
   begin_frame_spam();
   if (_gsg == (GraphicsStateGuardian *)NULL) {
     return false;
   }
-
+  if (_dxgsg -> _d3d_device == 0) {
+    return false;
+  }
+  
   if (mode == FM_render) {
-    begin_render_texture();
+    if (!save_bitplanes()) {
+      return false;
+    }
+    if (!rebuild_bitplanes()) {
+      restore_bitplanes();
+      return false;
+    }
     clear_cube_map_selection();
   }
 
@@ -111,7 +121,6 @@ end_frame(FrameMode mode, Thread *current_thread) {
   nassertv(_gsg != (GraphicsStateGuardian *)NULL);
 
   if (mode == FM_render) {
-    end_render_texture();
     copy_to_textures();
   }
 
@@ -123,162 +132,242 @@ end_frame(FrameMode mode, Thread *current_thread) {
       prepare_for_deletion();
     }
     clear_cube_map_selection();
+    restore_bitplanes();
   }
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: wglGraphicsStateGuardian::begin_render_texture
+//     Function: wglGraphicsStateGuardian::save_bitplanes
 //       Access: Public
-//  Description: If the GraphicsOutput supports direct render-to-texture,
-//               and if any setup needs to be done during begin_frame,
-//               then the setup code should go here.  Any textures that
-//               can not be rendered to directly should be reflagged
-//               as RTM_copy_texture.
+//  Description: After rendering, d3d_device will need to be restored 
+//               to its initial state.  This function saves the state.
 ////////////////////////////////////////////////////////////////////
-void wdxGraphicsBuffer9::
-begin_render_texture() {
-
-  if (_gsg != (GraphicsStateGuardian *)NULL) {
-
-    DXGraphicsStateGuardian9 *dxgsg;
-    DCAST_INTO_V(dxgsg, _gsg);
-
-    HRESULT hr;
-    bool state;
-    int render_target_index;
-
-    state = false;
-    render_target_index = 0;
-
-    DBG_S dxgsg9_cat.debug ( ) << "wdxGraphicsBuffer9::begin_render_texture\n"; DBG_E
-
-    if (dxgsg -> _d3d_device) {
-      Texture *tex = get_texture(0);
-      tex->set_render_to_texture(true);
-      TextureContext *tc = tex->prepare_now(_gsg->get_prepared_objects(), _gsg);
-
-      _dx_texture_context9 = DCAST (DXTextureContext9, tc);
-
-      // save render context
-      hr = dxgsg -> _d3d_device -> GetRenderTarget (render_target_index, &_back_buffer);
-      if (SUCCEEDED (hr)) {
-        hr = dxgsg -> _d3d_device -> GetDepthStencilSurface (&_z_stencil_buffer);
-        if (SUCCEEDED (hr)) {
-          state = true;
-        }
-        else {
-          dxgsg9_cat.error ( ) << "GetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
-        }
-      }
-      else {
-        dxgsg9_cat.error ( ) << "GetRenderTarget " << D3DERRORSTRING(hr) FL;
-      }
+bool wdxGraphicsBuffer9::
+save_bitplanes() {
+  HRESULT hr;
 
-      // set render context
-      if (state && _dx_texture_context9)
-      {
-        DXTextureContext9 *dx_texture_context9;
-
-        // use saved dx_texture_context9
-        dx_texture_context9 = _dx_texture_context9;
-
-        UINT mipmap_level;
-
-        mipmap_level = 0;
-        _direct_3d_surface = NULL;
-
-        // render to texture 2D
-        IDirect3DTexture9 *direct_3d_texture;
-
-        direct_3d_texture = dx_texture_context9 -> _d3d_2d_texture;
-        if (direct_3d_texture) {
-
-          // Make sure texturing is fully disabled (and all of our
-          // textures are therefore unbound in the GSG) before we try
-          // to render to this texture.
-          dxgsg->disable_texturing();
-
-          hr = direct_3d_texture -> GetSurfaceLevel (mipmap_level, &_direct_3d_surface);
-          if (SUCCEEDED (hr)) {
-            hr = dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, _direct_3d_surface);
-            if (SUCCEEDED (hr)) {
-              if (this -> _new_z_stencil_surface) {
-                hr = dxgsg -> _d3d_device -> SetDepthStencilSurface (this -> _new_z_stencil_surface);
-                if (SUCCEEDED (hr)) {
-
-                } else {
-                  dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
-                }
-              } else {
-                hr = dxgsg -> _d3d_device -> SetDepthStencilSurface (_z_stencil_buffer);
-                if (SUCCEEDED (hr)) {
-
-                } else {
-                  dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
-                }
-              }
-            } else {
-              dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
-            }
-          } else {
-            dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
-          }
-        }
-      }
-    }
+  hr = _dxgsg -> _d3d_device -> GetRenderTarget (0, &_saved_color_buffer);
+  if (!SUCCEEDED (hr)) {
+    dxgsg9_cat.error ( ) << "GetRenderTarget " << D3DERRORSTRING(hr) FL;
+    return false;
+  }
+  hr = _saved_color_buffer -> GetDesc (&_saved_color_desc);
+  if (!SUCCEEDED (hr)) {
+    dxgsg9_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL;
+    return false;
+  }
+  hr = _dxgsg -> _d3d_device -> GetDepthStencilSurface (&_saved_depth_buffer);
+  if (!SUCCEEDED (hr)) {
+    dxgsg9_cat.error ( ) << "GetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
+    return false;
   }
+  hr = _saved_depth_buffer -> GetDesc (&_saved_depth_desc);
+  if (!SUCCEEDED (hr)) {
+    dxgsg9_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL;
+    return false;
+  }
+  return true;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GraphicsOutput::end_render_texture
+//     Function: wglGraphicsStateGuardian::restore_bitplanes
 //       Access: Public
-//  Description: If the GraphicsOutput supports direct render-to-texture,
-//               and if any setup needs to be done during end_frame,
-//               then the setup code should go here.  Any textures that
-//               could not be rendered to directly should be reflagged
-//               as RTM_copy_texture.
+//  Description: After rendering, d3d_device will need to be restored 
+//               to its initial state.  This function restores the state.
 ////////////////////////////////////////////////////////////////////
 void wdxGraphicsBuffer9::
-end_render_texture() {
-
-DBG_S dxgsg9_cat.debug ( ) << "wdxGraphicsBuffer9::end_render_texture\n"; DBG_E
-
-  if (_gsg != (GraphicsStateGuardian *)NULL) {
+restore_bitplanes() {
+  DXGraphicsStateGuardian9 *dxgsg;
+  DCAST_INTO_V(dxgsg, _gsg);
+
+  HRESULT hr;
+  
+  hr = dxgsg -> _d3d_device ->
+    SetRenderTarget (0, _saved_color_buffer);
+  if (!SUCCEEDED (hr)) {
+    dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
+  }
+  hr = _dxgsg -> _d3d_device -> SetDepthStencilSurface (_saved_depth_buffer);
+  if (!SUCCEEDED (hr)) {
+    dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
+  }
+  
+  _saved_color_buffer->Release();
+  _saved_depth_buffer->Release();
+  _saved_color_buffer = NULL;
+  _saved_depth_buffer = NULL;
+}
 
-    DXGraphicsStateGuardian9 *dxgsg;
-    DCAST_INTO_V(dxgsg, _gsg);
 
-    if (dxgsg -> _d3d_device) {
-    // restore render context
-      HRESULT hr;
-      int render_target_index;
+////////////////////////////////////////////////////////////////////
+//     Function: wglGraphicsStateGuardian::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;
+  DXTextureContext9 *color_ctx = 0;
+  DXTextureContext9 *depth_ctx = 0;
+  IDirect3DTexture9 *color_d3d_tex = 0;
+  IDirect3DTexture9 *depth_d3d_tex = 0;
+  IDirect3DCubeTexture9 *color_cube = 0;
+  IDirect3DCubeTexture9 *depth_cube = 0;
+  IDirect3DSurface9 *color_surf = 0;
+  IDirect3DSurface9 *depth_surf = 0;
+
+  // Decide how big the bitplanes should be.
+
+  int bitplane_x = _x_size;
+  int bitplane_y = _y_size;
+  if (!_gsg->get_supports_tex_non_pow2()) {
+    bitplane_x = Texture::up_to_power_2(bitplane_x);
+    bitplane_y = Texture::up_to_power_2(bitplane_y);
+  }
 
-      render_target_index = 0;
+  // Find the color and depth textures.  Either may be present,
+  // or neither.  
+  //
+  // NOTE: Currently, depth-stencil textures are not implemented,
+  // but since it's coming soon, we're structuring for it.
+  
+  int color_tex_index = -1;
+  int depth_tex_index = -1;
+  for (int i=0; i<count_textures(); i++) {
+    if (get_rtm_mode(i) == RTM_bind_or_copy) {
+      if ((get_texture(i)->get_format() != Texture::F_depth_component)&&
+          (get_texture(i)->get_format() != Texture::F_stencil_index)&&
+          (color_tex_index < 0)) {
+        color_tex_index = i;
+      } else {
+        _textures[i]._rtm_mode = RTM_copy_texture;
+      }
+    }
+  }
+  
+
+  if (color_tex_index < 0) {
+    // Maintain the backing color surface.
+    if ((_color_backing_store)&&
+        ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
+      _color_backing_store->Release();
+      _color_backing_store = NULL;
+    }
+    if (!_color_backing_store) {
+      hr = _dxgsg -> _d3d_device ->
+        CreateOffscreenPlainSurface(bitplane_x, bitplane_y, _saved_color_desc.Format,
+                                    D3DPOOL_DEFAULT, &_color_backing_store, NULL);
+      if (!SUCCEEDED(hr)) {
+        dxgsg9_cat.error ( ) << "CreateImageSurface " << D3DERRORSTRING(hr) FL;
+      }
+    }
+    color_surf = _color_backing_store;
+  } else {
+    // Maintain the color texture.
+    if (_color_backing_store) {
+      _color_backing_store->Release();
+      _color_backing_store = NULL;
+    }
+    color_tex = get_texture(color_tex_index);
+    color_tex->set_x_size(bitplane_x);
+    color_tex->set_y_size(bitplane_y);
+    color_tex->set_format(Texture::F_rgba);
+    color_ctx = 
+      DCAST(DXTextureContext9,
+            color_tex->prepare_now(_gsg->get_prepared_objects(), _gsg));
+    if (color_tex->get_texture_type() == Texture::TT_2d_texture) {
+      color_d3d_tex = color_ctx->_d3d_2d_texture;
+      nassertr(color_d3d_tex != 0, false);
+      hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf);
+      if (!SUCCEEDED(hr)) {
+        dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
+      }
+    } else {
+      color_cube = color_ctx->_d3d_cube_texture;
+      nassertr(color_cube != 0, false);
+      hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf);
+      if (!SUCCEEDED(hr)) {
+        dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
+      }
+    }
+  }
 
-      if (_back_buffer) {
-        hr = dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, _back_buffer);
-        if (SUCCEEDED (hr)) {
-          _back_buffer -> Release ( );
-        } else {
-          dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
-        }
-        _back_buffer = NULL;
+  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 (!_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 (_z_stencil_buffer) {
-        hr = dxgsg -> _d3d_device -> SetDepthStencilSurface (_z_stencil_buffer);
-        if (SUCCEEDED (hr)) {
-          _z_stencil_buffer -> Release ( );
-        } else {
-          dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
-        }
-        _z_stencil_buffer = NULL;
+    }
+    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);
+    depth_tex->set_x_size(bitplane_x);
+    depth_tex->set_y_size(bitplane_y);
+    depth_tex->set_format(Texture::F_depth_component); // Should say depth_stencil
+    depth_ctx = 
+      DCAST(DXTextureContext9,
+            depth_tex->prepare_now(_gsg->get_prepared_objects(), _gsg));
+    if (depth_tex->get_texture_type() == Texture::TT_2d_texture) {
+      depth_d3d_tex = depth_ctx->_d3d_2d_texture;
+      nassertr(depth_d3d_tex != 0, false);
+      hr = color_d3d_tex -> GetSurfaceLevel(0, &depth_surf);
+      if (!SUCCEEDED(hr)) {
+        dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
       }
-      if (_direct_3d_surface) {
-        _direct_3d_surface -> Release ( );
-        _direct_3d_surface = NULL;
+    } else {
+      depth_cube = depth_ctx->_d3d_cube_texture;
+      nassertr(depth_cube != 0, false);
+      hr = depth_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &depth_surf);
+      if (!SUCCEEDED(hr)) {
+        dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
       }
     }
   }
+
+  _backing_sizex = bitplane_x;
+  _backing_sizey = bitplane_y;
+
+  // Load up the bitplanes.
+  
+  hr = _dxgsg -> _d3d_device -> SetRenderTarget (0, color_surf);
+  if (!SUCCEEDED (hr)) {
+    dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
+  }
+  
+  hr = _dxgsg -> _d3d_device -> SetDepthStencilSurface (depth_surf);
+  if (!SUCCEEDED (hr)) {
+    dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
+  }
+  
+  // Decrement the reference counts on these surfaces. The refcounts
+  // were incremented earlier when we called GetSurfaceLevel.
+
+  if ((color_surf != 0)&&(color_surf != _color_backing_store)) {
+    color_surf->Release();
+  }
+  if ((depth_surf != 0)&&(depth_surf != _depth_backing_store)) {
+    depth_surf->Release();
+  }
+  return true;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -292,77 +381,7 @@ DBG_S dxgsg9_cat.debug ( ) << "wdxGraphicsBuffer9::end_render_texture\n"; DBG_E
 ////////////////////////////////////////////////////////////////////
 void wdxGraphicsBuffer9::
 select_cube_map(int cube_map_index) {
-
-  if (_gsg != (GraphicsStateGuardian *)NULL) {
-
-    DXGraphicsStateGuardian9 *dxgsg;
-    DCAST_INTO_V(dxgsg, _gsg);
-
-    _cube_map_index = cube_map_index;
-
-    HRESULT hr;
-    UINT mipmap_level;
-    int render_target_index;
-    DXTextureContext9 *dx_texture_context9;
-
-    mipmap_level = 0;
-    render_target_index = 0;
-    dx_texture_context9 = _dx_texture_context9;
-
-    if (_direct_3d_surface) {
-        _direct_3d_surface -> Release ( );
-        _direct_3d_surface = NULL;
-    }
-
-    if (dxgsg -> _d3d_device) {
-
-      // render to cubemap face
-      IDirect3DCubeTexture9 *direct_3d_cube_texture;
-
-      direct_3d_cube_texture = dx_texture_context9 -> _d3d_cube_texture;
-      if (direct_3d_cube_texture) {
-        if (_cube_map_index >= 0 && _cube_map_index < 6) {
-          hr = direct_3d_cube_texture -> GetCubeMapSurface (
-            (D3DCUBEMAP_FACES) _cube_map_index, mipmap_level, &_direct_3d_surface);
-          if (SUCCEEDED (hr)) {
-
-            // Make sure texturing is fully disabled (and all of our
-            // textures are therefore unbound in the GSG) before we try
-            // to render to this texture.
-            dxgsg->disable_texturing();
-
-            hr = dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, _direct_3d_surface);
-            if (SUCCEEDED (hr)) {
-              if (this -> _new_z_stencil_surface) {
-                hr = dxgsg -> _d3d_device -> SetDepthStencilSurface (_new_z_stencil_surface);
-                if (SUCCEEDED (hr)) {
-
-                } else {
-                  dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
-                }
-              } else {
-                hr = dxgsg -> _d3d_device -> SetDepthStencilSurface (_z_stencil_buffer);
-                if (SUCCEEDED (hr)) {
-
-                } else {
-                  dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
-                }
-              }
-
-              DBG_S dxgsg9_cat.debug ( ) << "select_cube_map " << _cube_map_index << "\n";  DBG_E
-
-            } else {
-              dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
-            }
-          } else {
-            dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
-          }
-        } else {
-          dxgsg9_cat.error ( ) << "Invalid Cube Map Face Index " << _cube_map_index FL;
-        }
-      }
-    }
-  }
+  _cube_map_index = cube_map_index;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -399,23 +418,20 @@ void wdxGraphicsBuffer9::
 close_buffer() {
 
   if (_gsg != (GraphicsStateGuardian *)NULL) {
-    DXGraphicsStateGuardian9 *dxgsg;
-    DCAST_INTO_V(dxgsg, _gsg);
-
-    _dx_texture_context9 = NULL;
-
-    // release new depth stencil buffer if one was created
-    if (this -> _new_z_stencil_surface) {
-      this -> _new_z_stencil_surface -> Release ( );
-      this -> _new_z_stencil_surface = NULL;
-    }
-
     _gsg.clear();
-    _active = false;
+  }
+  
+  if (_color_backing_store) {
+    _color_backing_store->Release();
+    _color_backing_store = NULL;
+  }
+  if (_depth_backing_store) {
+    _depth_backing_store->Release();
+    _depth_backing_store = NULL;
   }
 
+  _active = false;
   _cube_map_index = -1;
-
   _is_valid = false;
 }
 
@@ -428,97 +444,26 @@ close_buffer() {
 ////////////////////////////////////////////////////////////////////
 bool wdxGraphicsBuffer9::
 open_buffer() {
-  bool state;
 
   // GSG creation/initialization.
   if (_gsg == 0) {
     _dxgsg = new DXGraphicsStateGuardian9(_pipe);
     _gsg = _dxgsg;
+  } else {
+    DCAST_INTO_R(_dxgsg, _gsg, false);
   }
-
-  // create texture
-  int tex_index;
-
-  state = false;
-  _is_valid = false;
-
-  // assume tex_index is 0
-  tex_index = 0;
-
-  Texture *tex = get_texture(tex_index);
-
-  // render to texture must be set
-  tex->set_render_to_texture(true);
-
-  TextureContext *tc = tex->prepare_now(_gsg->get_prepared_objects(), _gsg);
-  if (tc != NULL) {
-    HRESULT hr;
-    IDirect3DSurface9 *_depth_stencil_surface;
-
-    _dx_texture_context9 = DCAST (DXTextureContext9, tc);
-
-    // create a depth stencil buffer if needed
-    hr = _dxgsg -> _d3d_device -> GetDepthStencilSurface (&_depth_stencil_surface);
-    if (SUCCEEDED  (hr))
-    {
-      D3DSURFACE_DESC surface_description;
-
-      // get and copy the current depth stencil's parameters for the new buffer
-      hr = _depth_stencil_surface -> GetDesc (&surface_description);
-      if (SUCCEEDED  (hr)) {
-        UINT width;
-        UINT height;
-        D3DFORMAT format;
-        D3DMULTISAMPLE_TYPE multisample_type;
-        DWORD multisample_quality;
-        BOOL discard;
-
-        width = tex -> get_x_size ( );
-        height = tex -> get_y_size ( );
-
-        DBG_S dxgsg9_cat.debug ( ) << "-------------RTT SIZE " << "t width " << width << " t height " << height FL; DBG_E
-
-        if (surface_description.Width < width || surface_description.Height < height) {
-          format = surface_description.Format;
-          multisample_type = surface_description.MultiSampleType;
-          multisample_quality = surface_description.MultiSampleQuality;
-          discard = false;
-
-          hr = _dxgsg -> _d3d_device -> CreateDepthStencilSurface (
-            width, height, format, multisample_type, multisample_quality,
-            discard, &this -> _new_z_stencil_surface, NULL);
-          if (SUCCEEDED  (hr)) {
-
-            DBG_S dxgsg9_cat.debug ( ) << "-------------OK CreatedDepthStencilSurface " << D3DERRORSTRING(hr) FL; DBG_E
-
-            state = true;
-
-          } else {
-            dxgsg9_cat.error ( ) << "CreateDepthStencilSurface " << D3DERRORSTRING(hr) FL;
-          }
-        }
-        else {
-          // no need to create a separate depth stencil buffer since
-          // the current depth stencil buffer size is big enough
-          state = true;
-        }
-      }
-      else {
-        dxgsg9_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL;
-      }
-
-      _depth_stencil_surface -> Release ( );
-    }
-    else {
-      dxgsg9_cat.error ( ) << "GetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
-    }
-
-    if (state) {
-      _is_valid = true;
-    }
+  
+  if (!save_bitplanes()) {
+    return false;
   }
 
-  return state;
+  if (!rebuild_bitplanes()) {
+    restore_bitplanes();
+    return false;
+  }
+  
+  restore_bitplanes();
+  return true;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -541,4 +486,3 @@ process_1_event() {
   // Call window_proc
   DispatchMessage(&msg);
 }
-

+ 11 - 8
panda/src/dxgsg9/wdxGraphicsBuffer9.h

@@ -55,18 +55,21 @@ protected:
   virtual bool open_buffer();
 
 private:
-  void begin_render_texture();
-  void end_render_texture();
+  bool save_bitplanes();
+  bool rebuild_bitplanes();
+  void restore_bitplanes();
   static void process_1_event();
 
   int _cube_map_index;
   DXGraphicsStateGuardian9 *_dxgsg;
-  IDirect3DSurface9 *_back_buffer;
-  IDirect3DSurface9 *_z_stencil_buffer;
-  IDirect3DSurface9 *_direct_3d_surface;
-  DXTextureContext9 *_dx_texture_context9;
-
-  IDirect3DSurface9 *_new_z_stencil_surface;
+  IDirect3DSurface9 *_saved_color_buffer;
+  IDirect3DSurface9 *_saved_depth_buffer;
+  D3DSURFACE_DESC    _saved_color_desc;
+  D3DSURFACE_DESC    _saved_depth_desc;
+  IDirect3DSurface9 *_color_backing_store;
+  IDirect3DSurface9 *_depth_backing_store;
+  int _backing_sizex;
+  int _backing_sizey;
 
 public:
   static TypeHandle get_class_type() {