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