00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00027
00028
00029
00030 DXIndexBufferContext9::
00031 DXIndexBufferContext9(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
00032 IndexBufferContext(pgo, data),
00033 _ibuffer(NULL)
00034 {
00035 _managed = -1;
00036 }
00037
00038
00039
00040
00041
00042
00043 DXIndexBufferContext9::
00044 ~DXIndexBufferContext9() {
00045
00046 this -> free_ibuffer ( );
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
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
00074
00075
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
00100
00101
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
00157
00158
00159
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
00181
00182
00183
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 }