Panda3D
|
00001 // Filename: dxIndexBufferContext8.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 "dxIndexBufferContext8.h" 00016 #include "geomPrimitive.h" 00017 #include "config_dxgsg8.h" 00018 #include "graphicsStateGuardian.h" 00019 #include "pStatTimer.h" 00020 #include "dxgsg8base.h" 00021 00022 TypeHandle DXIndexBufferContext8::_type_handle; 00023 00024 //////////////////////////////////////////////////////////////////// 00025 // Function: DXIndexBufferContext8::Constructor 00026 // Access: Public 00027 // Description: 00028 //////////////////////////////////////////////////////////////////// 00029 DXIndexBufferContext8:: 00030 DXIndexBufferContext8(PreparedGraphicsObjects *pgo, GeomPrimitive *data) : 00031 IndexBufferContext(pgo, data), 00032 _ibuffer(NULL) 00033 { 00034 } 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Function: DXIndexBufferContext8::Destructor 00038 // Access: Public 00039 // Description: 00040 //////////////////////////////////////////////////////////////////// 00041 DXIndexBufferContext8:: 00042 ~DXIndexBufferContext8() { 00043 if (_ibuffer != NULL) { 00044 if (dxgsg8_cat.is_debug()) { 00045 dxgsg8_cat.debug() 00046 << "deleting index buffer " << _ibuffer << "\n"; 00047 } 00048 00049 RELEASE(_ibuffer, dxgsg8, "index buffer", RELEASE_ONCE); 00050 _ibuffer = NULL; 00051 } 00052 } 00053 00054 //////////////////////////////////////////////////////////////////// 00055 // Function: DXIndexBufferContext8::evict_lru 00056 // Access: Public, Virtual 00057 // Description: Evicts the page from the LRU. Called internally when 00058 // the LRU determines that it is full. May also be 00059 // called externally when necessary to explicitly evict 00060 // the page. 00061 // 00062 // It is legal for this method to either evict the page 00063 // as requested, do nothing (in which case the eviction 00064 // will be requested again at the next epoch), or 00065 // requeue itself on the tail of the queue (in which 00066 // case the eviction will be requested again much 00067 // later). 00068 //////////////////////////////////////////////////////////////////// 00069 void DXIndexBufferContext8:: 00070 evict_lru() { 00071 dequeue_lru(); 00072 00073 if (_ibuffer != NULL) { 00074 if (dxgsg8_cat.is_debug()) { 00075 dxgsg8_cat.debug() 00076 << "deleting index buffer " << _ibuffer << "\n"; 00077 } 00078 00079 RELEASE(_ibuffer, dxgsg8, "index buffer", RELEASE_ONCE); 00080 _ibuffer = NULL; 00081 } 00082 00083 update_data_size_bytes(0); 00084 mark_unloaded(); 00085 } 00086 00087 //////////////////////////////////////////////////////////////////// 00088 // Function: DXIndexBufferContext8::create_ibuffer 00089 // Access: Public 00090 // Description: Creates a new index buffer (but does not upload data 00091 // to it). 00092 //////////////////////////////////////////////////////////////////// 00093 void DXIndexBufferContext8:: 00094 create_ibuffer(DXScreenData &scrn, 00095 const GeomPrimitivePipelineReader *reader) { 00096 nassertv(reader->get_object() == get_data()); 00097 Thread *current_thread = reader->get_current_thread(); 00098 00099 if (_ibuffer != NULL) { 00100 RELEASE(_ibuffer, dxgsg8, "index buffer", RELEASE_ONCE); 00101 _ibuffer = NULL; 00102 } 00103 00104 PStatTimer timer(GraphicsStateGuardian::_create_index_buffer_pcollector, 00105 current_thread); 00106 00107 D3DFORMAT index_type = 00108 DXGraphicsStateGuardian8::get_index_type(reader->get_index_type()); 00109 00110 HRESULT hr = scrn._d3d_device->CreateIndexBuffer 00111 // (reader->get_data_size_bytes(), D3DUSAGE_WRITEONLY, 00112 // index_type, D3DPOOL_MANAGED, &_ibuffer); 00113 (reader->get_data_size_bytes(), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 00114 index_type, D3DPOOL_DEFAULT, &_ibuffer); 00115 if (FAILED(hr)) { 00116 dxgsg8_cat.warning() 00117 << "CreateIndexBuffer failed" << D3DERRORSTRING(hr); 00118 _ibuffer = NULL; 00119 } else { 00120 if (dxgsg8_cat.is_debug()) { 00121 dxgsg8_cat.debug() 00122 << "creating index buffer " << _ibuffer << ": " 00123 << reader->get_num_vertices() << " indices (" 00124 << reader->get_vertices_reader()->get_array_format()->get_column(0)->get_numeric_type() 00125 << ")\n"; 00126 } 00127 } 00128 } 00129 00130 //////////////////////////////////////////////////////////////////// 00131 // Function: DXIndexBufferContext8::upload_data 00132 // Access: Public 00133 // Description: Copies the latest data from the client store to 00134 // DirectX. 00135 //////////////////////////////////////////////////////////////////// 00136 bool DXIndexBufferContext8:: 00137 upload_data(const GeomPrimitivePipelineReader *reader, bool force) { 00138 nassertr(reader->get_object() == get_data(), false); 00139 Thread *current_thread = reader->get_current_thread(); 00140 00141 nassertr(_ibuffer != NULL, false); 00142 00143 const unsigned char *data_pointer = reader->get_read_pointer(force); 00144 if (data_pointer == NULL) { 00145 return false; 00146 } 00147 int data_size = reader->get_data_size_bytes(); 00148 00149 if (dxgsg8_cat.is_spam()) { 00150 dxgsg8_cat.spam() 00151 << "copying " << data_size 00152 << " bytes into index buffer " << _ibuffer << "\n"; 00153 } 00154 00155 PStatTimer timer(GraphicsStateGuardian::_load_index_buffer_pcollector, 00156 current_thread); 00157 00158 BYTE *local_pointer; 00159 // HRESULT hr = _ibuffer->Lock(0, data_size, &local_pointer, 0); 00160 HRESULT hr = _ibuffer->Lock(0, data_size, &local_pointer, D3DLOCK_DISCARD); 00161 if (FAILED(hr)) { 00162 dxgsg8_cat.error() 00163 << "IndexBuffer::Lock failed" << D3DERRORSTRING(hr); 00164 return false; 00165 } 00166 00167 GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size); 00168 memcpy(local_pointer, data_pointer, data_size); 00169 00170 _ibuffer->Unlock(); 00171 return true; 00172 } 00173