Panda3D
 All Classes Functions Variables Enumerations
dxIndexBufferContext9.cxx
00001 // Filename: dxIndexBufferContext9.cxx
00002 // Created by:  drose (18Mar05)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "dxIndexBufferContext9.h"
00016 #include "geomPrimitive.h"
00017 #include "config_dxgsg9.h"
00018 #include "graphicsStateGuardian.h"
00019 #include "pStatTimer.h"
00020 
00021 #define DEBUG_INDEX_BUFFER false
00022 
00023 TypeHandle DXIndexBufferContext9::_type_handle;
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //     Function: DXIndexBufferContext9::Constructor
00027 //       Access: Public
00028 //  Description:
00029 ////////////////////////////////////////////////////////////////////
00030 DXIndexBufferContext9::
00031 DXIndexBufferContext9(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
00032   IndexBufferContext(pgo, data),
00033   _ibuffer(NULL)
00034 {
00035   _managed = -1;
00036 }
00037 
00038 ////////////////////////////////////////////////////////////////////
00039 //     Function: DXIndexBufferContext9::Destructor
00040 //       Access: Public
00041 //  Description:
00042 ////////////////////////////////////////////////////////////////////
00043 DXIndexBufferContext9::
00044 ~DXIndexBufferContext9() {
00045 
00046   this -> free_ibuffer ( );
00047 }
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: DXIndexBufferContext9::evict_lru
00051 //       Access: Public, Virtual
00052 //  Description: Evicts the page from the LRU.  Called internally when
00053 //               the LRU determines that it is full.  May also be
00054 //               called externally when necessary to explicitly evict
00055 //               the page.
00056 //
00057 //               It is legal for this method to either evict the page
00058 //               as requested, do nothing (in which case the eviction
00059 //               will be requested again at the next epoch), or
00060 //               requeue itself on the tail of the queue (in which
00061 //               case the eviction will be requested again much
00062 //               later).
00063 ////////////////////////////////////////////////////////////////////
00064 void DXIndexBufferContext9::
00065 evict_lru() {
00066   dequeue_lru();
00067   free_ibuffer();
00068   update_data_size_bytes(0);
00069   mark_unloaded();
00070 }
00071 
00072 ////////////////////////////////////////////////////////////////////
00073 //     Function: DXIndexBufferContext9::free_ibuffer
00074 //       Access: Public
00075 //  Description: Free index buffer.
00076 ////////////////////////////////////////////////////////////////////
00077 void DXIndexBufferContext9::
00078 free_ibuffer(void) {
00079   if (_ibuffer != NULL) {
00080     if (DEBUG_INDEX_BUFFER && dxgsg9_cat.is_debug()) {
00081       dxgsg9_cat.debug()
00082         << "deleting index buffer " << _ibuffer << "\n";
00083     }
00084 
00085     if (DEBUG_INDEX_BUFFER)
00086     {
00087       RELEASE(_ibuffer, dxgsg9, "index buffer", RELEASE_ONCE);
00088     }
00089     else
00090     {
00091       _ibuffer -> Release ( );
00092     }
00093 
00094     _ibuffer = NULL;
00095   }
00096 }
00097 
00098 ////////////////////////////////////////////////////////////////////
00099 //     Function: DXIndexBufferContext9::allocate_ibuffer
00100 //       Access: Public
00101 //  Description: Allocates index buffer memory.
00102 ////////////////////////////////////////////////////////////////////
00103 void DXIndexBufferContext9::
00104 allocate_ibuffer(DXScreenData &scrn,
00105                  const GeomPrimitivePipelineReader *reader) {
00106 
00107   D3DFORMAT index_type =
00108     DXGraphicsStateGuardian9::get_index_type(reader->get_index_type());
00109 
00110   int data_size;
00111   DWORD usage;
00112   D3DPOOL pool;
00113 
00114   data_size = reader->get_data_size_bytes();
00115 
00116   _managed = scrn._managed_index_buffers;
00117   if (_managed)
00118   {
00119     usage = D3DUSAGE_WRITEONLY;
00120     pool = D3DPOOL_MANAGED;
00121   }
00122   else
00123   {
00124     usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC;
00125     pool = D3DPOOL_DEFAULT;
00126   }
00127 
00128   int attempts;
00129   HRESULT hr;
00130 
00131   attempts = 0;
00132   do
00133   {
00134      hr = scrn._d3d_device->CreateIndexBuffer
00135       (data_size, usage, index_type, pool, &_ibuffer, NULL);
00136      attempts++;
00137   }
00138   while (scrn._dxgsg9 -> check_dx_allocation (hr, data_size, attempts));
00139 
00140   if (FAILED(hr)) {
00141     dxgsg9_cat.warning()
00142       << "CreateIndexBuffer failed" << D3DERRORSTRING(hr);
00143     _ibuffer = NULL;
00144   } else {
00145     if (DEBUG_INDEX_BUFFER && dxgsg9_cat.is_debug()) {
00146       dxgsg9_cat.debug()
00147         << "creating index buffer " << _ibuffer << ": "
00148         << reader->get_num_vertices() << " indices ("
00149         << reader->get_vertices_reader()->get_array_format()->get_column(0)->get_numeric_type()
00150         << ")\n";
00151     }
00152   }
00153 }
00154 
00155 ////////////////////////////////////////////////////////////////////
00156 //     Function: DXIndexBufferContext9::create_ibuffer
00157 //       Access: Public
00158 //  Description: Creates a new index buffer (but does not upload data
00159 //               to it).
00160 ////////////////////////////////////////////////////////////////////
00161 void DXIndexBufferContext9::
00162 create_ibuffer(DXScreenData &scrn, 
00163                const GeomPrimitivePipelineReader *reader) {
00164   nassertv(reader->get_object() == get_data());
00165   Thread *current_thread = reader->get_current_thread();
00166 
00167   this -> free_ibuffer ( );
00168 
00169   PStatTimer timer(GraphicsStateGuardian::_create_index_buffer_pcollector,
00170                    current_thread);
00171 
00172   int data_size;
00173 
00174   data_size = reader->get_data_size_bytes();
00175 
00176   this -> allocate_ibuffer(scrn, reader);
00177 }
00178 
00179 ////////////////////////////////////////////////////////////////////
00180 //     Function: DXIndexBufferContext9::upload_data
00181 //       Access: Public
00182 //  Description: Copies the latest data from the client store to
00183 //               DirectX.
00184 ////////////////////////////////////////////////////////////////////
00185 bool DXIndexBufferContext9::
00186 upload_data(const GeomPrimitivePipelineReader *reader, bool force) {
00187   nassertr(reader->get_object() == get_data(), false);
00188   Thread *current_thread = reader->get_current_thread();
00189 
00190   nassertr(_ibuffer != NULL, false);
00191 
00192   const unsigned char *data_pointer = reader->get_read_pointer(force);
00193   if (data_pointer == NULL) {
00194     return false;
00195   }
00196   int data_size = reader->get_data_size_bytes();
00197 
00198   if (dxgsg9_cat.is_spam()) {
00199     dxgsg9_cat.spam()
00200       << "copying " << data_size
00201       << " bytes into index buffer " << _ibuffer << "\n";
00202   }
00203   PStatTimer timer(GraphicsStateGuardian::_load_index_buffer_pcollector,
00204                    current_thread);
00205 
00206   HRESULT hr;
00207   BYTE *local_pointer;
00208 
00209   if (_managed)
00210   {
00211     hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, 0);
00212   }
00213   else
00214   {
00215     hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, D3DLOCK_DISCARD);
00216   }
00217   if (FAILED(hr)) {
00218     dxgsg9_cat.error()
00219       << "IndexBuffer::Lock failed" << D3DERRORSTRING(hr);
00220     return false;
00221   }
00222 
00223   GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
00224   memcpy(local_pointer, data_pointer, data_size);
00225 
00226   _ibuffer->Unlock();
00227   return true;
00228 }
 All Classes Functions Variables Enumerations