Panda3D
 All Classes Functions Variables Enumerations
dxIndexBufferContext9.cxx
1 // Filename: dxIndexBufferContext9.cxx
2 // Created by: drose (18Mar05)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "dxIndexBufferContext9.h"
16 #include "geomPrimitive.h"
17 #include "config_dxgsg9.h"
18 #include "graphicsStateGuardian.h"
19 #include "pStatTimer.h"
20 
21 #define DEBUG_INDEX_BUFFER false
22 
23 TypeHandle DXIndexBufferContext9::_type_handle;
24 
25 ////////////////////////////////////////////////////////////////////
26 // Function: DXIndexBufferContext9::Constructor
27 // Access: Public
28 // Description:
29 ////////////////////////////////////////////////////////////////////
30 DXIndexBufferContext9::
31 DXIndexBufferContext9(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
32  IndexBufferContext(pgo, data),
33  _ibuffer(NULL)
34 {
35  _managed = -1;
36 }
37 
38 ////////////////////////////////////////////////////////////////////
39 // Function: DXIndexBufferContext9::Destructor
40 // Access: Public
41 // Description:
42 ////////////////////////////////////////////////////////////////////
43 DXIndexBufferContext9::
44 ~DXIndexBufferContext9() {
45 
46  this -> free_ibuffer ( );
47 }
48 
49 ////////////////////////////////////////////////////////////////////
50 // Function: DXIndexBufferContext9::evict_lru
51 // Access: Public, Virtual
52 // Description: Evicts the page from the LRU. Called internally when
53 // the LRU determines that it is full. May also be
54 // called externally when necessary to explicitly evict
55 // the page.
56 //
57 // It is legal for this method to either evict the page
58 // as requested, do nothing (in which case the eviction
59 // will be requested again at the next epoch), or
60 // requeue itself on the tail of the queue (in which
61 // case the eviction will be requested again much
62 // later).
63 ////////////////////////////////////////////////////////////////////
66  dequeue_lru();
67  free_ibuffer();
69  mark_unloaded();
70 }
71 
72 ////////////////////////////////////////////////////////////////////
73 // Function: DXIndexBufferContext9::free_ibuffer
74 // Access: Public
75 // Description: Free index buffer.
76 ////////////////////////////////////////////////////////////////////
78 free_ibuffer(void) {
79  if (_ibuffer != NULL) {
80  if (DEBUG_INDEX_BUFFER && dxgsg9_cat.is_debug()) {
81  dxgsg9_cat.debug()
82  << "deleting index buffer " << _ibuffer << "\n";
83  }
84 
85  if (DEBUG_INDEX_BUFFER)
86  {
87  RELEASE(_ibuffer, dxgsg9, "index buffer", RELEASE_ONCE);
88  }
89  else
90  {
91  _ibuffer -> Release ( );
92  }
93 
94  _ibuffer = NULL;
95  }
96 }
97 
98 ////////////////////////////////////////////////////////////////////
99 // Function: DXIndexBufferContext9::allocate_ibuffer
100 // Access: Public
101 // Description: Allocates index buffer memory.
102 ////////////////////////////////////////////////////////////////////
105  const GeomPrimitivePipelineReader *reader) {
106 
107  D3DFORMAT index_type =
108  DXGraphicsStateGuardian9::get_index_type(reader->get_index_type());
109 
110  int data_size;
111  DWORD usage;
112  D3DPOOL pool;
113 
114  data_size = reader->get_data_size_bytes();
115 
116  _managed = scrn._managed_index_buffers;
117  if (_managed)
118  {
119  usage = D3DUSAGE_WRITEONLY;
120  pool = D3DPOOL_MANAGED;
121  }
122  else
123  {
124  usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC;
125  pool = D3DPOOL_DEFAULT;
126  }
127 
128  int attempts;
129  HRESULT hr;
130 
131  attempts = 0;
132  do
133  {
134  hr = scrn._d3d_device->CreateIndexBuffer
135  (data_size, usage, index_type, pool, &_ibuffer, NULL);
136  attempts++;
137  }
138  while (scrn._dxgsg9 -> check_dx_allocation (hr, data_size, attempts));
139 
140  if (FAILED(hr)) {
141  dxgsg9_cat.warning()
142  << "CreateIndexBuffer failed" << D3DERRORSTRING(hr);
143  _ibuffer = NULL;
144  } else {
145  if (DEBUG_INDEX_BUFFER && dxgsg9_cat.is_debug()) {
146  dxgsg9_cat.debug()
147  << "creating index buffer " << _ibuffer << ": "
148  << reader->get_num_vertices() << " indices ("
149  << reader->get_vertices_reader()->get_array_format()->get_column(0)->get_numeric_type()
150  << ")\n";
151  }
152  }
153 }
154 
155 ////////////////////////////////////////////////////////////////////
156 // Function: DXIndexBufferContext9::create_ibuffer
157 // Access: Public
158 // Description: Creates a new index buffer (but does not upload data
159 // to it).
160 ////////////////////////////////////////////////////////////////////
163  const GeomPrimitivePipelineReader *reader) {
164  nassertv(reader->get_object() == get_data());
165  Thread *current_thread = reader->get_current_thread();
166 
167  this -> free_ibuffer ( );
168 
169  PStatTimer timer(GraphicsStateGuardian::_create_index_buffer_pcollector,
170  current_thread);
171 
172  int data_size;
173 
174  data_size = reader->get_data_size_bytes();
175 
176  this -> allocate_ibuffer(scrn, reader);
177 }
178 
179 ////////////////////////////////////////////////////////////////////
180 // Function: DXIndexBufferContext9::upload_data
181 // Access: Public
182 // Description: Copies the latest data from the client store to
183 // DirectX.
184 ////////////////////////////////////////////////////////////////////
186 upload_data(const GeomPrimitivePipelineReader *reader, bool force) {
187  nassertr(reader->get_object() == get_data(), false);
188  Thread *current_thread = reader->get_current_thread();
189 
190  nassertr(_ibuffer != NULL, false);
191 
192  const unsigned char *data_pointer = reader->get_read_pointer(force);
193  if (data_pointer == NULL) {
194  return false;
195  }
196  int data_size = reader->get_data_size_bytes();
197 
198  if (dxgsg9_cat.is_spam()) {
199  dxgsg9_cat.spam()
200  << "copying " << data_size
201  << " bytes into index buffer " << _ibuffer << "\n";
202  }
203  PStatTimer timer(GraphicsStateGuardian::_load_index_buffer_pcollector,
204  current_thread);
205 
206  HRESULT hr;
207  BYTE *local_pointer;
208 
209  if (_managed)
210  {
211  hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, 0);
212  }
213  else
214  {
215  hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, D3DLOCK_DISCARD);
216  }
217  if (FAILED(hr)) {
218  dxgsg9_cat.error()
219  << "IndexBuffer::Lock failed" << D3DERRORSTRING(hr);
220  return false;
221  }
222 
223  GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
224  memcpy(local_pointer, data_pointer, data_size);
225 
226  _ibuffer->Unlock();
227  return true;
228 }
This is a special class object that holds all the information returned by a particular GSG to indicat...
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:63
static D3DFORMAT get_index_type(Geom::NumericType numeric_type)
Maps from the Geom&#39;s internal numeric type symbols to DirectX&#39;s.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition: pStatTimer.h:34
A table of objects that are saved within the graphics context for reference by handle later...
void dequeue_lru()
Removes the page from its AdaptiveLru.
Definition: adaptiveLru.I:171
void allocate_ibuffer(DXScreenData &scrn, const GeomPrimitivePipelineReader *reader)
Allocates index buffer memory.
GeomPrimitive * get_data() const
Returns the pointer to the client-side array data object.
void mark_unloaded()
Should be called after the buffer has been forced out of graphics memory.
bool upload_data(const GeomPrimitivePipelineReader *reader, bool force)
Copies the latest data from the client store to DirectX.
int get_data_size_bytes() const
Returns the number of bytes stored in the vertices array.
A thread; that is, a lightweight process.
Definition: thread.h:51
virtual void evict_lru()
Evicts the page from the LRU.
void free_ibuffer()
Free index buffer.
void create_ibuffer(DXScreenData &scrn, const GeomPrimitivePipelineReader *reader)
Creates a new index buffer (but does not upload data to it).
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
void update_data_size_bytes(size_t new_data_size_bytes)
Should be called (usually by a derived class) when the on-card size of this object has changed...