Support uint8 indices in DX9 renderer

This commit is contained in:
rdb 2016-07-10 15:48:17 +02:00
parent c34758ea5c
commit e098da9030
3 changed files with 33 additions and 23 deletions

View File

@ -24,6 +24,7 @@ This issue fixes several bugs that were still found in 1.9.2.
* Fix assertion when using aux render targets in DX9 * Fix assertion when using aux render targets in DX9
* Work around Cg bug generating invalid ASM for saturated tex loads * Work around Cg bug generating invalid ASM for saturated tex loads
* Fix issues with certain Cg shader inputs in DX9 * Fix issues with certain Cg shader inputs in DX9
* Support uint8 index buffers in DX9
------------------------ RELEASE 1.9.2 ------------------------ ------------------------ RELEASE 1.9.2 ------------------------

View File

@ -3584,6 +3584,8 @@ bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
D3DFORMAT DXGraphicsStateGuardian9:: D3DFORMAT DXGraphicsStateGuardian9::
get_index_type(Geom::NumericType numeric_type) { get_index_type(Geom::NumericType numeric_type) {
switch (numeric_type) { switch (numeric_type) {
// NT_uint8 is automatically promoted to uint16.
case Geom::NT_uint8:
case Geom::NT_uint16: case Geom::NT_uint16:
return D3DFMT_INDEX16; return D3DFMT_INDEX16;

View File

@ -30,9 +30,8 @@ TypeHandle DXIndexBufferContext9::_type_handle;
DXIndexBufferContext9:: DXIndexBufferContext9::
DXIndexBufferContext9(PreparedGraphicsObjects *pgo, GeomPrimitive *data) : DXIndexBufferContext9(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
IndexBufferContext(pgo, data), IndexBufferContext(pgo, data),
_ibuffer(NULL) _ibuffer(NULL),
{ _managed(-1) {
_managed = -1;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -42,8 +41,7 @@ DXIndexBufferContext9(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
DXIndexBufferContext9:: DXIndexBufferContext9::
~DXIndexBufferContext9() { ~DXIndexBufferContext9() {
free_ibuffer();
this -> free_ibuffer ( );
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -82,13 +80,10 @@ free_ibuffer(void) {
<< "deleting index buffer " << _ibuffer << "\n"; << "deleting index buffer " << _ibuffer << "\n";
} }
if (DEBUG_INDEX_BUFFER) if (DEBUG_INDEX_BUFFER) {
{
RELEASE(_ibuffer, dxgsg9, "index buffer", RELEASE_ONCE); RELEASE(_ibuffer, dxgsg9, "index buffer", RELEASE_ONCE);
} } else {
else _ibuffer->Release();
{
_ibuffer -> Release ( );
} }
_ibuffer = NULL; _ibuffer = NULL;
@ -113,6 +108,11 @@ allocate_ibuffer(DXScreenData &scrn,
data_size = reader->get_data_size_bytes(); data_size = reader->get_data_size_bytes();
if (reader->get_index_type() == GeomEnums::NT_uint8) {
// We widen 8-bits indices to 16-bits.
data_size *= 2;
}
_managed = scrn._managed_index_buffers; _managed = scrn._managed_index_buffers;
if (_managed) if (_managed)
{ {
@ -164,16 +164,12 @@ create_ibuffer(DXScreenData &scrn,
nassertv(reader->get_object() == get_data()); nassertv(reader->get_object() == get_data());
Thread *current_thread = reader->get_current_thread(); Thread *current_thread = reader->get_current_thread();
this -> free_ibuffer ( ); free_ibuffer();
PStatTimer timer(GraphicsStateGuardian::_create_index_buffer_pcollector, PStatTimer timer(GraphicsStateGuardian::_create_index_buffer_pcollector,
current_thread); current_thread);
int data_size; allocate_ibuffer(scrn, reader);
data_size = reader->get_data_size_bytes();
this -> allocate_ibuffer(scrn, reader);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -195,6 +191,11 @@ upload_data(const GeomPrimitivePipelineReader *reader, bool force) {
} }
int data_size = reader->get_data_size_bytes(); int data_size = reader->get_data_size_bytes();
if (reader->get_index_type() == GeomEnums::NT_uint8) {
// We widen 8-bits indices to 16-bits.
data_size *= 2;
}
if (dxgsg9_cat.is_spam()) { if (dxgsg9_cat.is_spam()) {
dxgsg9_cat.spam() dxgsg9_cat.spam()
<< "copying " << data_size << "copying " << data_size
@ -206,12 +207,9 @@ upload_data(const GeomPrimitivePipelineReader *reader, bool force) {
HRESULT hr; HRESULT hr;
BYTE *local_pointer; BYTE *local_pointer;
if (_managed) if (_managed) {
{
hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, 0); hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, 0);
} } else {
else
{
hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, D3DLOCK_DISCARD); hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, D3DLOCK_DISCARD);
} }
if (FAILED(hr)) { if (FAILED(hr)) {
@ -221,7 +219,16 @@ upload_data(const GeomPrimitivePipelineReader *reader, bool force) {
} }
GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size); GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
memcpy(local_pointer, data_pointer, data_size);
if (reader->get_index_type() == GeomEnums::NT_uint8) {
// Widen to 16-bits, as DirectX doesn't support 8-bits indices.
PN_uint16 *ptr = (PN_uint16 *)local_pointer;
for (size_t i = 0; i < data_size; i += 2) {
*ptr++ = (PN_uint16)*data_pointer++;
}
} else {
memcpy(local_pointer, data_pointer, data_size);
}
_ibuffer->Unlock(); _ibuffer->Unlock();
return true; return true;