Panda3D
|
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 }