From 823524e43ce229d7e74a5b95f03c3aa53c7f71ed Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 8 Jun 2007 15:38:45 +0000 Subject: [PATCH] more aggressive dxgsg8/9 deferred loading --- panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 51 +++++++---- panda/src/dxgsg8/dxGraphicsStateGuardian8.h | 8 +- panda/src/dxgsg8/dxIndexBufferContext8.cxx | 22 +++-- panda/src/dxgsg8/dxIndexBufferContext8.h | 2 +- panda/src/dxgsg8/dxVertexBufferContext8.cxx | 22 +++-- panda/src/dxgsg8/dxVertexBufferContext8.h | 2 +- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 84 +++++++++++++++---- panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 8 +- panda/src/dxgsg9/dxIndexBufferContext9.cxx | 21 +++-- panda/src/dxgsg9/dxIndexBufferContext9.h | 2 +- panda/src/dxgsg9/dxVertexBufferContext9.cxx | 21 +++-- panda/src/dxgsg9/dxVertexBufferContext9.h | 2 +- panda/src/pgraph/config_pgraph.h | 2 +- 13 files changed, 172 insertions(+), 75 deletions(-) diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 9fdcd0ddf3..ae2a068de2 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -303,9 +303,9 @@ prepare_vertex_buffer(GeomVertexArrayData *data) { // Description: Updates the vertex buffer with the current data, and // makes it the current vertex buffer for rendering. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian8:: +bool DXGraphicsStateGuardian8:: apply_vertex_buffer(VertexBufferContext *vbc, - const GeomVertexArrayDataHandle *reader) { + const GeomVertexArrayDataHandle *reader, bool force) { DXVertexBufferContext8 *dvbc = DCAST(DXVertexBufferContext8, vbc); if (dvbc->_vbuffer == NULL) { @@ -316,7 +316,9 @@ apply_vertex_buffer(VertexBufferContext *vbc, } if (dvbc->_vbuffer != NULL) { - dvbc->upload_data(reader); + if (!dvbc->upload_data(reader, force)) { + return false; + } dvbc->mark_loaded(reader); @@ -338,7 +340,9 @@ apply_vertex_buffer(VertexBufferContext *vbc, dvbc->create_vbuffer(*_screen, reader); } - dvbc->upload_data(reader); + if (!dvbc->upload_data(reader, force)) { + return false; + } dvbc->mark_loaded(reader); _active_vbuffer = NULL; } @@ -360,6 +364,7 @@ apply_vertex_buffer(VertexBufferContext *vbc, << ") failed" << D3DERRORSTRING(hr); } #endif + return true; } //////////////////////////////////////////////////////////////////// @@ -401,9 +406,9 @@ prepare_index_buffer(GeomPrimitive *data) { // Description: Updates the index buffer with the current data, and // makes it the current index buffer for rendering. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian8:: +bool DXGraphicsStateGuardian8:: apply_index_buffer(IndexBufferContext *ibc, - const GeomPrimitivePipelineReader *reader) { + const GeomPrimitivePipelineReader *reader, bool force) { DXIndexBufferContext8 *dibc = DCAST(DXIndexBufferContext8, ibc); if (dibc->_ibuffer == NULL) { @@ -411,7 +416,9 @@ apply_index_buffer(IndexBufferContext *ibc, dibc->create_ibuffer(*_screen, reader); if (dibc->_ibuffer != NULL) { - dibc->upload_data(reader); + if (!dibc->upload_data(reader, force)) { + return false; + } dibc->mark_loaded(reader); _d3d_device->SetIndices(dibc->_ibuffer, 0); @@ -431,7 +438,9 @@ apply_index_buffer(IndexBufferContext *ibc, dibc->create_ibuffer(*_screen, reader); } - dibc->upload_data(reader); + if (!dibc->upload_data(reader, force)) { + return false; + } dibc->mark_loaded(reader); _active_ibuffer = NULL; @@ -443,6 +452,8 @@ apply_index_buffer(IndexBufferContext *ibc, dibc->set_active(true); } } + + return true; } //////////////////////////////////////////////////////////////////// @@ -812,7 +823,9 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, VertexBufferContext *vbc = ((GeomVertexArrayData *)(data->get_object()))->prepare_now(get_prepared_objects(), this); nassertr(vbc != (VertexBufferContext *)NULL, false); - apply_vertex_buffer(vbc, data); + if (!apply_vertex_buffer(vbc, data, force)) { + return false; + } const GeomVertexAnimationSpec &animation = data_reader->get_format()->get_animation(); @@ -917,7 +930,9 @@ draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { // Indexed, vbuffers. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); nassertr(ibc != (IndexBufferContext *)NULL, false); - apply_index_buffer(ibc, reader); + if (!apply_index_buffer(ibc, reader, force)) { + return false; + } _d3d_device->DrawIndexedPrimitive (D3DPT_TRIANGLELIST, @@ -987,7 +1002,9 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { // Indexed, vbuffers, one line triangle strip. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); nassertr(ibc != (IndexBufferContext *)NULL, false); - apply_index_buffer(ibc, reader); + if (!apply_index_buffer(ibc, reader, force)) { + return false; + } _d3d_device->DrawIndexedPrimitive (D3DPT_TRIANGLESTRIP, @@ -1055,7 +1072,9 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { // Indexed, vbuffers, individual triangle strips. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); nassertr(ibc != (IndexBufferContext *)NULL, false); - apply_index_buffer(ibc, reader); + if (!apply_index_buffer(ibc, reader, force)) { + return false; + } unsigned int start = 0; for (size_t i = 0; i < ends.size(); i++) { @@ -1165,7 +1184,9 @@ draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { // Indexed, vbuffers. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); nassertr(ibc != (IndexBufferContext *)NULL, false); - apply_index_buffer(ibc, reader); + if (!apply_index_buffer(ibc, reader, force)) { + return false; + } unsigned int start = 0; for (size_t i = 0; i < ends.size(); i++) { @@ -1265,7 +1286,9 @@ draw_lines(const GeomPrimitivePipelineReader *reader, bool force) { // Indexed, vbuffers. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); nassertr(ibc != (IndexBufferContext *)NULL, false); - apply_index_buffer(ibc, reader); + if (!apply_index_buffer(ibc, reader, force)) { + return false; + } _d3d_device->DrawIndexedPrimitive (D3DPT_LINELIST, diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 58a2ec07f9..6c373c5aa0 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -56,13 +56,13 @@ public: virtual void release_texture(TextureContext *tc); virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data); - void apply_vertex_buffer(VertexBufferContext *vbc, - const GeomVertexArrayDataHandle *reader); + bool apply_vertex_buffer(VertexBufferContext *vbc, + const GeomVertexArrayDataHandle *reader, bool force); virtual void release_vertex_buffer(VertexBufferContext *vbc); virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data); - void apply_index_buffer(IndexBufferContext *ibc, - const GeomPrimitivePipelineReader *reader); + bool apply_index_buffer(IndexBufferContext *ibc, + const GeomPrimitivePipelineReader *reader, bool force); virtual void release_index_buffer(IndexBufferContext *ibc); virtual PT(GeomMunger) make_geom_munger(const RenderState *state, diff --git a/panda/src/dxgsg8/dxIndexBufferContext8.cxx b/panda/src/dxgsg8/dxIndexBufferContext8.cxx index 37e4e0b764..0c76ce73d1 100644 --- a/panda/src/dxgsg8/dxIndexBufferContext8.cxx +++ b/panda/src/dxgsg8/dxIndexBufferContext8.cxx @@ -104,15 +104,17 @@ create_ibuffer(DXScreenData &scrn, // Description: Copies the latest data from the client store to // DirectX. //////////////////////////////////////////////////////////////////// -void DXIndexBufferContext8:: -upload_data(const GeomPrimitivePipelineReader *reader) { - nassertv(reader->get_object() == get_data()); +bool DXIndexBufferContext8:: +upload_data(const GeomPrimitivePipelineReader *reader, bool force) { + nassertr(reader->get_object() == get_data(), false); Thread *current_thread = reader->get_current_thread(); - nassertv(_ibuffer != NULL); - PStatTimer timer(GraphicsStateGuardian::_load_index_buffer_pcollector, - current_thread); + nassertr(_ibuffer != NULL, false); + const unsigned char *data_pointer = reader->get_read_pointer(force); + if (data_pointer == NULL) { + return false; + } int data_size = reader->get_data_size_bytes(); if (dxgsg8_cat.is_spam()) { @@ -121,18 +123,22 @@ upload_data(const GeomPrimitivePipelineReader *reader) { << " bytes into index buffer " << _ibuffer << "\n"; } + PStatTimer timer(GraphicsStateGuardian::_load_index_buffer_pcollector, + current_thread); + BYTE *local_pointer; // HRESULT hr = _ibuffer->Lock(0, data_size, &local_pointer, 0); HRESULT hr = _ibuffer->Lock(0, data_size, &local_pointer, D3DLOCK_DISCARD); if (FAILED(hr)) { dxgsg8_cat.error() << "IndexBuffer::Lock failed" << D3DERRORSTRING(hr); - return; + return false; } GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size); - memcpy(local_pointer, reader->get_read_pointer(true), data_size); + memcpy(local_pointer, data_pointer, data_size); _ibuffer->Unlock(); + return true; } diff --git a/panda/src/dxgsg8/dxIndexBufferContext8.h b/panda/src/dxgsg8/dxIndexBufferContext8.h index aea549a4a7..2b5d8d77b0 100644 --- a/panda/src/dxgsg8/dxIndexBufferContext8.h +++ b/panda/src/dxgsg8/dxIndexBufferContext8.h @@ -35,7 +35,7 @@ public: void create_ibuffer(DXScreenData &scrn, const GeomPrimitivePipelineReader *reader); - void upload_data(const GeomPrimitivePipelineReader *reader); + bool upload_data(const GeomPrimitivePipelineReader *reader, bool force); IDirect3DIndexBuffer8 *_ibuffer; diff --git a/panda/src/dxgsg8/dxVertexBufferContext8.cxx b/panda/src/dxgsg8/dxVertexBufferContext8.cxx index ac91942d14..a3e06f03a7 100644 --- a/panda/src/dxgsg8/dxVertexBufferContext8.cxx +++ b/panda/src/dxgsg8/dxVertexBufferContext8.cxx @@ -231,14 +231,16 @@ create_vbuffer(DXScreenData &scrn, // Description: Copies the latest data from the client store to // DirectX. //////////////////////////////////////////////////////////////////// -void DXVertexBufferContext8:: -upload_data(const GeomVertexArrayDataHandle *reader) { - nassertv(reader->get_object() == get_data()); - nassertv(_vbuffer != NULL); +bool DXVertexBufferContext8:: +upload_data(const GeomVertexArrayDataHandle *reader, bool force) { + nassertr(reader->get_object() == get_data(), false); + nassertr(_vbuffer != NULL, false); Thread *current_thread = reader->get_current_thread(); - PStatTimer timer(GraphicsStateGuardian::_load_vertex_buffer_pcollector, - current_thread); + const unsigned char *data_pointer = reader->get_read_pointer(force); + if (data_pointer == NULL) { + return false; + } int data_size = reader->get_data_size_bytes(); if (dxgsg8_cat.is_spam()) { @@ -247,18 +249,22 @@ upload_data(const GeomVertexArrayDataHandle *reader) { << " bytes into vertex buffer " << _vbuffer << "\n"; } + PStatTimer timer(GraphicsStateGuardian::_load_vertex_buffer_pcollector, + current_thread); + BYTE *local_pointer; // HRESULT hr = _vbuffer->Lock(0, data_size, &local_pointer, 0); HRESULT hr = _vbuffer->Lock(0, data_size, &local_pointer, D3DLOCK_DISCARD); if (FAILED(hr)) { dxgsg8_cat.error() << "VertexBuffer::Lock failed" << D3DERRORSTRING(hr); - return; + return false; } GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size); - memcpy(local_pointer, reader->get_read_pointer(true), data_size); + memcpy(local_pointer, data_pointer, data_size); _vbuffer->Unlock(); + return true; } diff --git a/panda/src/dxgsg8/dxVertexBufferContext8.h b/panda/src/dxgsg8/dxVertexBufferContext8.h index d908d73e9b..395ff54eaf 100644 --- a/panda/src/dxgsg8/dxVertexBufferContext8.h +++ b/panda/src/dxgsg8/dxVertexBufferContext8.h @@ -35,7 +35,7 @@ public: void create_vbuffer(DXScreenData &scrn, const GeomVertexArrayDataHandle *reader); - void upload_data(const GeomVertexArrayDataHandle *reader); + bool upload_data(const GeomVertexArrayDataHandle *reader, bool force); IDirect3DVertexBuffer8 *_vbuffer; int _fvf; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 76d42ed1cf..a678d6ae64 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -62,6 +62,7 @@ #include "pStatTimer.h" #include "pStatCollector.h" #include "wdxGraphicsBuffer9.h" +#include "config_pgraph.h" #ifdef HAVE_CG #include "Cg/cgD3D9.h" #endif @@ -391,10 +392,10 @@ prepare_vertex_buffer(GeomVertexArrayData *data) { // Description: Updates the vertex buffer with the current data, and // makes it the current vertex buffer for rendering. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian9:: +bool DXGraphicsStateGuardian9:: apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context, - const GeomVertexArrayDataHandle *reader) { + const GeomVertexArrayDataHandle *reader, bool force) { DXVertexBufferContext9 *dvbc = DCAST(DXVertexBufferContext9, vbc); DBG_SH3 dxgsg9_cat.debug ( ) << "apply_vertex_buffer\n"; DBG_E @@ -420,7 +421,9 @@ apply_vertex_buffer(VertexBufferContext *vbc, } if (dvbc->_vbuffer != NULL) { - dvbc->upload_data(reader); + if (!dvbc->upload_data(reader, force)) { + return false; + } dvbc->mark_loaded(reader); @@ -438,7 +441,9 @@ apply_vertex_buffer(VertexBufferContext *vbc, dvbc->create_vbuffer(*_screen, reader); } - dvbc->upload_data(reader); + if (!dvbc->upload_data(reader, force)) { + return false; + } dvbc->mark_loaded(reader); _active_vbuffer = NULL; @@ -565,6 +570,8 @@ apply_vertex_buffer(VertexBufferContext *vbc, } } } + + return true; } //////////////////////////////////////////////////////////////////// @@ -606,9 +613,9 @@ prepare_index_buffer(GeomPrimitive *data) { // Description: Updates the index buffer with the current data, and // makes it the current index buffer for rendering. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian9:: +bool DXGraphicsStateGuardian9:: apply_index_buffer(IndexBufferContext *ibc, - const GeomPrimitivePipelineReader *reader) { + const GeomPrimitivePipelineReader *reader, bool force) { DXIndexBufferContext9 *dibc = DCAST(DXIndexBufferContext9, ibc); if (_lru) { @@ -620,7 +627,9 @@ apply_index_buffer(IndexBufferContext *ibc, dibc->create_ibuffer(*_screen, reader); if (dibc->_ibuffer != NULL) { - dibc->upload_data(reader); + if (!dibc->upload_data(reader, force)) { + return false; + } dibc->mark_loaded(reader); _d3d_device->SetIndices(dibc->_ibuffer); @@ -640,7 +649,9 @@ apply_index_buffer(IndexBufferContext *ibc, dibc->create_ibuffer(*_screen, reader); } - dibc->upload_data(reader); + if (!dibc->upload_data(reader, force)) { + return false; + } dibc->mark_loaded(reader); _active_ibuffer = NULL; @@ -652,6 +663,8 @@ apply_index_buffer(IndexBufferContext *ibc, dibc->set_active(true); } } + + return true; } //////////////////////////////////////////////////////////////////// @@ -1367,7 +1380,9 @@ vertex_element_array -> vertex_element_type_array; VertexBufferContext *vbc = ((GeomVertexArrayData *)(data->get_object()))->prepare_now(get_prepared_objects(), this); nassertr(vbc != (VertexBufferContext *)NULL, false); - apply_vertex_buffer(vbc, _current_shader_context, data); + if (!apply_vertex_buffer(vbc, _current_shader_context, data, force)) { + return false; + } const GeomVertexAnimationSpec &animation = data_reader->get_format()->get_animation(); @@ -1475,7 +1490,9 @@ draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { // Indexed, vbuffers. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); nassertr(ibc != (IndexBufferContext *)NULL, false); - apply_index_buffer(ibc, reader); + if (!apply_index_buffer(ibc, reader, force)) { + return false; + } //DBG_SH2 dxgsg9_cat.debug ( ) << "DrawIndexedPrimitive \n"; DBG_E @@ -1561,7 +1578,9 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { // Indexed, vbuffers, one line triangle strip. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); nassertr(ibc != (IndexBufferContext *)NULL, false); - apply_index_buffer(ibc, reader); + if (!apply_index_buffer(ibc, reader, force)) { + return false; + } //dxgsg9_cat.error ( ) << "DrawIndexedPrimitive D3DPT_TRIANGLESTRIP VERTICES: " << reader->get_num_vertices ( ) << "\n"; @@ -1637,7 +1656,9 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { // Indexed, vbuffers, individual triangle strips. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); nassertr(ibc != (IndexBufferContext *)NULL, false); - apply_index_buffer(ibc, reader); + if (!apply_index_buffer(ibc, reader, force)) { + return false; + } unsigned int start = 0; for (size_t i = 0; i < ends.size(); i++) { @@ -1751,7 +1772,9 @@ draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { // Indexed, vbuffers. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); nassertr(ibc != (IndexBufferContext *)NULL, false); - apply_index_buffer(ibc, reader); + if (!apply_index_buffer(ibc, reader, force)) { + return false; + } unsigned int start = 0; for (size_t i = 0; i < ends.size(); i++) { @@ -1851,7 +1874,9 @@ draw_lines(const GeomPrimitivePipelineReader *reader, bool force) { // Indexed, vbuffers. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); nassertr(ibc != (IndexBufferContext *)NULL, false); - apply_index_buffer(ibc, reader); + if (!apply_index_buffer(ibc, reader, force)) { + return false; + } _d3d_device->DrawIndexedPrimitive (D3DPT_LINELIST, @@ -2349,10 +2374,23 @@ bool vertex_buffer_page_in_function (LruPage *lru_page) // allocate vertex buffer Thread *current_thread = Thread::get_current_thread(); CPT(GeomVertexArrayDataHandle) reader = vertex_buffer->get_data()->get_handle(current_thread); + + /* + Not sure if this is the correct thing to do. Can we return false + from the page_in function? Will we get called again next frame if + we do? + if (allow_incomplete_render) { + // Check if the data is resident before continuing. + const unsigned char *data_pointer = reader->get_read_pointer(false); + if (data_pointer == NULL) { + return false; + } + } + */ vertex_buffer -> allocate_vbuffer (*(gsg->_screen), reader); // update vertex buffer - vertex_buffer -> upload_data(reader); + vertex_buffer -> upload_data(reader, true); vertex_buffer -> set_resident(true); if (DEBUG_LRU && dxgsg9_cat.is_debug()) @@ -2390,10 +2428,24 @@ bool index_buffer_page_in_function (LruPage *lru_page) // allocate vertex buffer Thread *current_thread = Thread::get_current_thread(); GeomPrimitivePipelineReader reader(index_buffer->get_data(), current_thread); + + /* + Not sure if this is the correct thing to do. Can we return false + from the page_in function? Will we get called again next frame if + we do? + if (allow_incomplete_render) { + // Check if the data is resident before continuing. + const unsigned char *data_pointer = reader.get_read_pointer(false); + if (data_pointer == NULL) { + return false; + } + } + */ + index_buffer -> allocate_ibuffer (*(gsg->_screen), &reader); // update vertex buffer - index_buffer -> upload_data (&reader); + index_buffer -> upload_data (&reader, true); index_buffer -> set_resident(true); if (DEBUG_LRU && dxgsg9_cat.is_debug()) diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index afdc3abdad..22be2043f6 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -93,13 +93,13 @@ public: void release_shader(ShaderContext *sc); virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data); - void apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context, - const GeomVertexArrayDataHandle *reader); + bool apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context, + const GeomVertexArrayDataHandle *reader, bool force); virtual void release_vertex_buffer(VertexBufferContext *vbc); virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data); - void apply_index_buffer(IndexBufferContext *ibc, - const GeomPrimitivePipelineReader *reader); + bool apply_index_buffer(IndexBufferContext *ibc, + const GeomPrimitivePipelineReader *reader, bool force); virtual void release_index_buffer(IndexBufferContext *ibc); virtual void begin_occlusion_query(); diff --git a/panda/src/dxgsg9/dxIndexBufferContext9.cxx b/panda/src/dxgsg9/dxIndexBufferContext9.cxx index fe331e2249..2539bf8fe4 100755 --- a/panda/src/dxgsg9/dxIndexBufferContext9.cxx +++ b/panda/src/dxgsg9/dxIndexBufferContext9.cxx @@ -202,15 +202,17 @@ create_ibuffer(DXScreenData &scrn, // Description: Copies the latest data from the client store to // DirectX. //////////////////////////////////////////////////////////////////// -void DXIndexBufferContext9:: -upload_data(const GeomPrimitivePipelineReader *reader) { - nassertv(reader->get_object() == get_data()); +bool DXIndexBufferContext9:: +upload_data(const GeomPrimitivePipelineReader *reader, bool force) { + nassertr(reader->get_object() == get_data(), false); Thread *current_thread = reader->get_current_thread(); - nassertv(_ibuffer != NULL); - PStatTimer timer(GraphicsStateGuardian::_load_index_buffer_pcollector, - current_thread); + nassertr(_ibuffer != NULL, false); + const unsigned char *data_pointer = reader->get_read_pointer(force); + if (data_pointer == NULL) { + return false; + } int data_size = reader->get_data_size_bytes(); if (dxgsg9_cat.is_spam()) { @@ -218,6 +220,8 @@ upload_data(const GeomPrimitivePipelineReader *reader) { << "copying " << data_size << " bytes into index buffer " << _ibuffer << "\n"; } + PStatTimer timer(GraphicsStateGuardian::_load_index_buffer_pcollector, + current_thread); HRESULT hr; BYTE *local_pointer; @@ -233,11 +237,12 @@ upload_data(const GeomPrimitivePipelineReader *reader) { if (FAILED(hr)) { dxgsg9_cat.error() << "IndexBuffer::Lock failed" << D3DERRORSTRING(hr); - return; + return false; } GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size); - memcpy(local_pointer, reader->get_read_pointer(true), data_size); + memcpy(local_pointer, data_pointer, data_size); _ibuffer->Unlock(); + return true; } diff --git a/panda/src/dxgsg9/dxIndexBufferContext9.h b/panda/src/dxgsg9/dxIndexBufferContext9.h index ad0892ff51..92c67cf95a 100755 --- a/panda/src/dxgsg9/dxIndexBufferContext9.h +++ b/panda/src/dxgsg9/dxIndexBufferContext9.h @@ -36,7 +36,7 @@ public: void free_ibuffer(); void allocate_ibuffer(DXScreenData &scrn, const GeomPrimitivePipelineReader *reader); void create_ibuffer(DXScreenData &scrn, const GeomPrimitivePipelineReader *reader); - void upload_data(const GeomPrimitivePipelineReader *reader); + bool upload_data(const GeomPrimitivePipelineReader *reader, bool force); IDirect3DIndexBuffer9 *_ibuffer; int _managed; diff --git a/panda/src/dxgsg9/dxVertexBufferContext9.cxx b/panda/src/dxgsg9/dxVertexBufferContext9.cxx index 08df06e7d9..b2a6b5fece 100755 --- a/panda/src/dxgsg9/dxVertexBufferContext9.cxx +++ b/panda/src/dxgsg9/dxVertexBufferContext9.cxx @@ -441,14 +441,16 @@ create_vbuffer(DXScreenData &scrn, // Description: Copies the latest data from the client store to // DirectX. //////////////////////////////////////////////////////////////////// -void DXVertexBufferContext9:: -upload_data(const GeomVertexArrayDataHandle *reader) { - nassertv(reader->get_object() == get_data()); - nassertv(_vbuffer != NULL); +bool DXVertexBufferContext9:: +upload_data(const GeomVertexArrayDataHandle *reader, bool force) { + nassertr(reader->get_object() == get_data(), false); + nassertr(_vbuffer != NULL, false); Thread *current_thread = reader->get_current_thread(); - PStatTimer timer(GraphicsStateGuardian::_load_vertex_buffer_pcollector, - current_thread); + const unsigned char *data_pointer = reader->get_read_pointer(force); + if (data_pointer == NULL) { + return false; + } int data_size = reader->get_data_size_bytes(); if (dxgsg9_cat.is_spam()) { @@ -456,6 +458,8 @@ upload_data(const GeomVertexArrayDataHandle *reader) { << "copying " << data_size << " bytes into vertex buffer " << _vbuffer << "\n"; } + PStatTimer timer(GraphicsStateGuardian::_load_vertex_buffer_pcollector, + current_thread); HRESULT hr; BYTE *local_pointer; @@ -469,11 +473,12 @@ upload_data(const GeomVertexArrayDataHandle *reader) { if (FAILED(hr)) { dxgsg9_cat.error() << "VertexBuffer::Lock failed" << D3DERRORSTRING(hr); - return; + return false; } GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size); - memcpy(local_pointer, reader->get_read_pointer(true), data_size); + memcpy(local_pointer, data_pointer, data_size); _vbuffer->Unlock(); + return true; } diff --git a/panda/src/dxgsg9/dxVertexBufferContext9.h b/panda/src/dxgsg9/dxVertexBufferContext9.h index 1385ebeef0..4981067798 100755 --- a/panda/src/dxgsg9/dxVertexBufferContext9.h +++ b/panda/src/dxgsg9/dxVertexBufferContext9.h @@ -36,7 +36,7 @@ public: void free_vbuffer(); void allocate_vbuffer(DXScreenData &scrn, const GeomVertexArrayDataHandle *reader); void create_vbuffer(DXScreenData &scrn, const GeomVertexArrayDataHandle *reader); - void upload_data(const GeomVertexArrayDataHandle *reader); + bool upload_data(const GeomVertexArrayDataHandle *reader, bool force); IDirect3DVertexBuffer9 *_vbuffer; int _fvf; diff --git a/panda/src/pgraph/config_pgraph.h b/panda/src/pgraph/config_pgraph.h index 861e7755e8..61b1e208b7 100644 --- a/panda/src/pgraph/config_pgraph.h +++ b/panda/src/pgraph/config_pgraph.h @@ -69,7 +69,7 @@ extern ConfigVariableBool m_dual_flash; extern ConfigVariableList load_file_type; extern ConfigVariableString default_model_extension; -extern ConfigVariableBool allow_incomplete_render; +extern EXPCL_PANDA ConfigVariableBool allow_incomplete_render; extern EXPCL_PANDA void init_libpgraph();