protect vbuffer and ibuffer from multiple sets; work around Quadro driver bug
This commit is contained in:
parent
052e1bb02c
commit
46cdf502bb
|
|
@ -62,6 +62,18 @@ ConfigVariableBool dx_show_cursor_watermark
|
|||
ConfigVariableBool dx_use_triangle_mipgen_filter
|
||||
("dx-use-triangle-mipgen-filter", false);
|
||||
|
||||
ConfigVariableBool dx_broken_max_index
|
||||
("dx-broken-max-index", false,
|
||||
PRC_DESC("Configure this true if you have a buggy graphics driver that "
|
||||
"doesn't correctly implement the third parameter, NumVertices, "
|
||||
"of DrawIndexedPrimitive(). In particular, the NVIDIA Quadro "
|
||||
"driver version 6.14.10.7184 seems to treat this as a maximum "
|
||||
"vertex index, rather than a delta between the maximum and "
|
||||
"minimum vertex index. Turn this on if you are seeing stray "
|
||||
"triangles, or you are not seeing all of your triangles. Enabling "
|
||||
"this should work around this bug, at the cost of some additional "
|
||||
"rendering overhead on the GPU."));
|
||||
|
||||
#ifndef NDEBUG
|
||||
// debugging flag
|
||||
// values are same as D3DCULL enumtype, 0 - no force, 1 - force none, 2 - force CW, 3 - force CCW
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ extern ConfigVariableBool dx_use_rangebased_fog;
|
|||
extern ConfigVariableBool link_tristrips;
|
||||
extern ConfigVariableInt dx_multisample_antialiasing_level;
|
||||
extern ConfigVariableBool dx_use_triangle_mipgen_filter;
|
||||
extern ConfigVariableBool dx_broken_max_index;
|
||||
|
||||
|
||||
// debug flags we might want to use in full optimized build
|
||||
|
|
|
|||
|
|
@ -204,8 +204,8 @@ DXGraphicsStateGuardian8(const FrameBufferProperties &properties) :
|
|||
_pFvfBufBasePtr = NULL;
|
||||
_index_buf=NULL;
|
||||
|
||||
_vbuffer_active = false;
|
||||
_ibuffer_active = false;
|
||||
_active_vbuffer = NULL;
|
||||
_active_ibuffer = NULL;
|
||||
|
||||
// _max_light_range = __D3DLIGHT_RANGE_MAX;
|
||||
|
||||
|
|
@ -2740,7 +2740,10 @@ draw_triangles(const qpGeomTriangles *primitive) {
|
|||
_vertices_tri_pcollector.add_level(primitive->get_num_vertices());
|
||||
_primitive_batches_tri_pcollector.add_level(1);
|
||||
if (primitive->is_indexed()) {
|
||||
if (_vbuffer_active) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers.
|
||||
IndexBufferContext *ibc = ((qpGeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
|
|
@ -2748,8 +2751,7 @@ draw_triangles(const qpGeomTriangles *primitive) {
|
|||
|
||||
_pD3DDevice->DrawIndexedPrimitive
|
||||
(D3DPT_TRIANGLELIST,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
|
||||
min_vertex, max_vertex - min_vertex + 1,
|
||||
0, primitive->get_num_primitives());
|
||||
|
||||
} else {
|
||||
|
|
@ -2758,8 +2760,7 @@ draw_triangles(const qpGeomTriangles *primitive) {
|
|||
|
||||
_pD3DDevice->DrawIndexedPrimitiveUP
|
||||
(D3DPT_TRIANGLELIST,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
|
||||
min_vertex, max_vertex - min_vertex + 1,
|
||||
primitive->get_num_primitives(),
|
||||
primitive->get_data(),
|
||||
index_type,
|
||||
|
|
@ -2767,7 +2768,7 @@ draw_triangles(const qpGeomTriangles *primitive) {
|
|||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
if (_vbuffer_active) {
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers.
|
||||
_pD3DDevice->DrawPrimitive
|
||||
(D3DPT_TRIANGLELIST,
|
||||
|
|
@ -2794,8 +2795,6 @@ draw_triangles(const qpGeomTriangles *primitive) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
draw_tristrips(const qpGeomTristrips *primitive) {
|
||||
int min_vertex = primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
|
||||
|
||||
if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) {
|
||||
|
|
@ -2804,7 +2803,10 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
|||
_vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
|
||||
_primitive_batches_tristrip_pcollector.add_level(1);
|
||||
if (primitive->is_indexed()) {
|
||||
if (_vbuffer_active) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers, one line triangle strip.
|
||||
IndexBufferContext *ibc = ((qpGeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
|
|
@ -2826,7 +2828,7 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
|||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
if (_vbuffer_active) {
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers, one long triangle strip.
|
||||
_pD3DDevice->DrawPrimitive
|
||||
(D3DPT_TRIANGLESTRIP,
|
||||
|
|
@ -2861,7 +2863,7 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
|||
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
primitive->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
|
||||
if (_vbuffer_active) {
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, client arrays, individual triangle strips.
|
||||
IndexBufferContext *ibc = ((qpGeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
|
|
@ -2902,7 +2904,7 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (_vbuffer_active) {
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, client arrays, individual triangle strips.
|
||||
unsigned int first_vertex = primitive->get_first_vertex();
|
||||
unsigned int start = 0;
|
||||
|
|
@ -2947,7 +2949,7 @@ draw_trifans(const qpGeomTrifans *primitive) {
|
|||
_primitive_batches_trifan_pcollector.add_level(ends.size());
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
int min_vertex = primitive->get_min_vertex();
|
||||
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
|
||||
|
||||
|
|
@ -2960,7 +2962,7 @@ draw_trifans(const qpGeomTrifans *primitive) {
|
|||
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
primitive->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
|
||||
if (_vbuffer_active) {
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers.
|
||||
IndexBufferContext *ibc = ((qpGeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
|
|
@ -3001,7 +3003,7 @@ draw_trifans(const qpGeomTrifans *primitive) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (_vbuffer_active) {
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers.
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
|
|
@ -3044,7 +3046,10 @@ draw_lines(const qpGeomLines *primitive) {
|
|||
_primitive_batches_other_pcollector.add_level(1);
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
if (_vbuffer_active) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers.
|
||||
IndexBufferContext *ibc = ((qpGeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
|
|
@ -3052,8 +3057,7 @@ draw_lines(const qpGeomLines *primitive) {
|
|||
|
||||
_pD3DDevice->DrawIndexedPrimitive
|
||||
(D3DPT_LINELIST,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
|
||||
min_vertex, max_vertex - min_vertex + 1,
|
||||
0, primitive->get_num_primitives());
|
||||
|
||||
} else {
|
||||
|
|
@ -3062,8 +3066,7 @@ draw_lines(const qpGeomLines *primitive) {
|
|||
|
||||
_pD3DDevice->DrawIndexedPrimitiveUP
|
||||
(D3DPT_LINELIST,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
|
||||
min_vertex, max_vertex - min_vertex + 1,
|
||||
primitive->get_num_primitives(),
|
||||
primitive->get_data(),
|
||||
index_type,
|
||||
|
|
@ -3071,7 +3074,7 @@ draw_lines(const qpGeomLines *primitive) {
|
|||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
if (_vbuffer_active) {
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers.
|
||||
_pD3DDevice->DrawPrimitive
|
||||
(D3DPT_LINELIST, primitive->get_first_vertex(),
|
||||
|
|
@ -3359,20 +3362,19 @@ apply_vertex_buffer(VertexBufferContext *vbc) {
|
|||
if (dvbc->_vbuffer != NULL) {
|
||||
dvbc->upload_data();
|
||||
|
||||
add_to_vertex_buffer_record(dvbc);
|
||||
add_to_total_buffer_record(dvbc);
|
||||
dvbc->mark_loaded();
|
||||
|
||||
_pD3DDevice->SetStreamSource
|
||||
(0, dvbc->_vbuffer, dvbc->get_data()->get_array_format()->get_stride());
|
||||
_vbuffer_active = true;
|
||||
_active_vbuffer = dvbc;
|
||||
add_to_vertex_buffer_record(dvbc);
|
||||
|
||||
} else {
|
||||
_vbuffer_active = false;
|
||||
_active_vbuffer = NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
add_to_vertex_buffer_record(dvbc);
|
||||
|
||||
if (dvbc->was_modified()) {
|
||||
if (dvbc->changed_size()) {
|
||||
// We have to destroy the old vertex buffer and create a new
|
||||
|
|
@ -3384,11 +3386,15 @@ apply_vertex_buffer(VertexBufferContext *vbc) {
|
|||
|
||||
add_to_total_buffer_record(dvbc);
|
||||
dvbc->mark_loaded();
|
||||
_active_vbuffer = NULL;
|
||||
}
|
||||
|
||||
_pD3DDevice->SetStreamSource
|
||||
(0, dvbc->_vbuffer, dvbc->get_data()->get_array_format()->get_stride());
|
||||
_vbuffer_active = true;
|
||||
if (_active_vbuffer != dvbc) {
|
||||
_pD3DDevice->SetStreamSource
|
||||
(0, dvbc->_vbuffer, dvbc->get_data()->get_array_format()->get_stride());
|
||||
_active_vbuffer = dvbc;
|
||||
add_to_vertex_buffer_record(dvbc);
|
||||
}
|
||||
}
|
||||
|
||||
set_vertex_format(dvbc->_fvf);
|
||||
|
|
@ -3443,21 +3449,19 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
|||
|
||||
if (dibc->_ibuffer != NULL) {
|
||||
dibc->upload_data();
|
||||
add_to_index_buffer_record(dibc);
|
||||
add_to_total_buffer_record(dibc);
|
||||
dibc->mark_loaded();
|
||||
|
||||
_pD3DDevice->SetIndices(dibc->_ibuffer, 0);
|
||||
_ibuffer_active = true;
|
||||
} else {
|
||||
_active_ibuffer = dibc;
|
||||
add_to_index_buffer_record(dibc);
|
||||
|
||||
} else {
|
||||
_pD3DDevice->SetIndices(NULL, 0);
|
||||
_ibuffer_active = false;
|
||||
_active_ibuffer = NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
add_to_index_buffer_record(dibc);
|
||||
|
||||
if (dibc->was_modified()) {
|
||||
if (dibc->changed_size()) {
|
||||
// We have to destroy the old index buffer and create a new
|
||||
|
|
@ -3469,10 +3473,14 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
|||
|
||||
add_to_total_buffer_record(dibc);
|
||||
dibc->mark_loaded();
|
||||
_active_ibuffer = NULL;
|
||||
}
|
||||
|
||||
_pD3DDevice->SetIndices(dibc->_ibuffer, 0);
|
||||
_ibuffer_active = true;
|
||||
if (_active_ibuffer != dibc) {
|
||||
_pD3DDevice->SetIndices(dibc->_ibuffer, 0);
|
||||
_active_ibuffer = dibc;
|
||||
add_to_index_buffer_record(dibc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ extern void dbgPrintVidMem(LPDIRECTDRAW7 pDD, LPDDSCAPS2 lpddsCaps,const char *p
|
|||
#define PRINTVIDMEM(pDD,pCaps,pMsg)
|
||||
#endif
|
||||
|
||||
class DXVertexBufferContext8;
|
||||
class DXIndexBufferContext8;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DXGraphicsStateGuardian8
|
||||
// Description : A GraphicsStateGuardian specialized for rendering
|
||||
|
|
@ -327,8 +330,8 @@ protected:
|
|||
int _projection_mat_stack_count;
|
||||
|
||||
CPT(DisplayRegion) _actual_display_region;
|
||||
bool _vbuffer_active;
|
||||
bool _ibuffer_active;
|
||||
const DXVertexBufferContext8 *_active_vbuffer;
|
||||
const DXIndexBufferContext8 *_active_ibuffer;
|
||||
|
||||
// Color/Alpha Matrix Transition stuff
|
||||
INLINE void transform_color(Colorf &InColor,D3DCOLOR &OutColor);
|
||||
|
|
|
|||
Loading…
Reference in New Issue