Skip to content

Commit 291d6a7

Browse files
committed
tr_surface: parallel IQM model CPU runtime computation
1 parent 13f01b3 commit 291d6a7

File tree

1 file changed

+142
-38
lines changed

1 file changed

+142
-38
lines changed

src/engine/renderer/tr_surface.cpp

Lines changed: 142 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2121
===========================================================================
2222
*/
2323
// tr_surface.c
24+
#include "framework/Omp.h"
2425
#include "tr_local.h"
2526
#include "gl_shader.h"
2627
#include "Material.h"
@@ -42,6 +43,9 @@ use the shader system.
4243

4344
static transform_t bones[ MAX_BONES ];
4445

46+
// Test cvar.
47+
Cvar::Cvar<bool> r_parallelNotbntoq( "r_parallelNotbntoq", "r_parallelNotbntoq", Cvar::NONE, true );
48+
4549
/*
4650
==============
4751
Tess_EndBegin
@@ -1242,6 +1246,10 @@ void Tess_SurfaceIQM( srfIQModel_t *surf ) {
12421246
shaderVertex_t *tessVertex = tess.verts + tess.numVertexes;
12431247
shaderVertex_t *lastVertex = tessVertex + surf->num_vertexes;
12441248

1249+
size_t num_chunks = Omp::GetThreads();
1250+
1251+
size_t chunk_size = surf->num_vertexes / num_chunks;
1252+
12451253
// Deform the vertices by the lerped bones.
12461254
if ( model->num_joints > 0 && model->blendWeights && model->blendIndexes )
12471255
{
@@ -1252,6 +1260,7 @@ void Tess_SurfaceIQM( srfIQModel_t *surf ) {
12521260
byte *modelBlendIndex = model->blendIndexes + 4 * firstVertex;
12531261
byte *modelBlendWeight = model->blendWeights + 4 * firstVertex;
12541262

1263+
if ( !r_parallelNotbntoq.Get() ) {
12551264
for ( ; tessVertex < lastVertex; tessVertex++,
12561265
modelPosition += 3, modelNormal += 3,
12571266
modelTangent += 3, modelBitangent += 3,
@@ -1280,71 +1289,166 @@ void Tess_SurfaceIQM( srfIQModel_t *surf ) {
12801289

12811290
Vector2Copy( modelTexcoord, tessVertex->texCoords );
12821291
}
1292+
} else {
1293+
auto task = [&]( const size_t& chunk_index ) -> void
1294+
{
1295+
size_t chunk_offset = chunk_index * chunk_size;
1296+
1297+
shaderVertex_t *chunk_tessVertex = tessVertex + chunk_offset;
1298+
float *chunk_modelPosition = modelPosition + 3 * chunk_offset;
1299+
float *chunk_modelNormal = modelNormal + 3 * chunk_offset;
1300+
float *chunk_modelTangent = modelTangent + 3 * chunk_offset;
1301+
float *chunk_modelBitangent = modelBitangent + 3 * chunk_offset;
1302+
float *chunk_modelTexcoord = modelTexcoord + 2 * chunk_offset;
1303+
byte *chunk_modelBlendIndex = modelBlendIndex + 4 * chunk_offset;
1304+
byte *chunk_modelBlendWeight = modelBlendWeight + 4 * chunk_offset;
1305+
1306+
shaderVertex_t *chunk_lastVertex =
1307+
chunk_index == num_chunks - 1
1308+
? lastVertex
1309+
: chunk_tessVertex + chunk_size;
1310+
1311+
for ( ; chunk_tessVertex < chunk_lastVertex;
1312+
chunk_tessVertex++,
1313+
chunk_modelPosition += 3, chunk_modelNormal += 3,
1314+
chunk_modelTangent += 3, chunk_modelBitangent += 3,
1315+
chunk_modelTexcoord += 2 )
1316+
{
1317+
vec3_t position = {};
1318+
1319+
byte *chunk_lastBlendIndex = chunk_modelBlendIndex + 4;
1320+
1321+
for ( ; chunk_modelBlendIndex < chunk_lastBlendIndex;
1322+
chunk_modelBlendIndex++,
1323+
chunk_modelBlendWeight++ )
1324+
{
1325+
if ( *chunk_modelBlendWeight == 0 )
1326+
{
1327+
continue;
1328+
}
1329+
1330+
float weight = *chunk_modelBlendWeight * weightFactor;
1331+
vec3_t tmp;
1332+
1333+
TransformPoint( &bones[ *chunk_modelBlendIndex ], chunk_modelPosition, tmp );
1334+
VectorMA( position, weight, tmp, position );
1335+
}
1336+
1337+
VectorCopy( position, tessVertex->xyz );
1338+
1339+
Vector2Copy( chunk_modelTexcoord, tessVertex->texCoords );
1340+
}
1341+
};
1342+
1343+
Omp::Tasker( task, num_chunks );
1344+
}
12831345
}
12841346
else
12851347
{
12861348
byte *modelBlendIndex = model->blendIndexes + 4 * firstVertex;
12871349
byte *modelBlendWeight = model->blendWeights + 4 * firstVertex;
12881350

1289-
for ( ; tessVertex < lastVertex; tessVertex++,
1290-
modelPosition += 3, modelNormal += 3,
1291-
modelTangent += 3, modelBitangent += 3,
1292-
modelTexcoord += 2 )
1351+
auto task = [&]( const size_t& chunk_index ) -> void
12931352
{
1294-
vec3_t position = {}, tangent = {}, binormal = {}, normal = {};
1353+
size_t chunk_offset = chunk_index * chunk_size;
1354+
1355+
shaderVertex_t *chunk_tessVertex = tessVertex + chunk_offset;
1356+
float *chunk_modelPosition = modelPosition + 3 * chunk_offset;
1357+
float *chunk_modelNormal = modelNormal + 3 * chunk_offset;
1358+
float *chunk_modelTangent = modelTangent + 3 * chunk_offset;
1359+
float *chunk_modelBitangent = modelBitangent + 3 * chunk_offset;
1360+
float *chunk_modelTexcoord = modelTexcoord + 2 * chunk_offset;
1361+
byte *chunk_modelBlendIndex = modelBlendIndex + 4 * chunk_offset;
1362+
byte *chunk_modelBlendWeight = modelBlendWeight + 4 * chunk_offset;
1363+
1364+
shaderVertex_t *chunk_lastVertex =
1365+
chunk_index == num_chunks - 1
1366+
? lastVertex
1367+
: chunk_tessVertex + chunk_size;
1368+
1369+
for ( ; chunk_tessVertex < chunk_lastVertex;
1370+
chunk_tessVertex++,
1371+
chunk_modelPosition += 3, chunk_modelNormal += 3,
1372+
chunk_modelTangent += 3, chunk_modelBitangent += 3,
1373+
chunk_modelTexcoord += 2 )
1374+
{
1375+
vec3_t position = {}, tangent = {}, binormal = {}, normal = {};
12951376

1296-
byte *lastBlendIndex = modelBlendIndex + 4;
1377+
byte *chunk_lastBlendIndex = chunk_modelBlendIndex + 4;
12971378

1298-
for ( ; modelBlendIndex < lastBlendIndex; modelBlendIndex++,
1299-
modelBlendWeight++ )
1300-
{
1301-
if ( *modelBlendWeight == 0 )
1379+
for ( ; chunk_modelBlendIndex < chunk_lastBlendIndex;
1380+
chunk_modelBlendIndex++,
1381+
chunk_modelBlendWeight++ )
13021382
{
1303-
continue;
1304-
}
1383+
if ( *chunk_modelBlendWeight == 0 )
1384+
{
1385+
continue;
1386+
}
13051387

1306-
float weight = *modelBlendWeight * weightFactor;
1307-
vec3_t tmp;
1388+
float weight = *chunk_modelBlendWeight * weightFactor;
1389+
vec3_t tmp;
13081390

1309-
TransformPoint( &bones[ *modelBlendIndex ], modelPosition, tmp );
1310-
VectorMA( position, weight, tmp, position );
1391+
TransformPoint( &bones[ *chunk_modelBlendIndex ], chunk_modelPosition, tmp );
1392+
VectorMA( position, weight, tmp, position );
13111393

1312-
TransformNormalVector( &bones[ *modelBlendIndex ], modelNormal, tmp );
1313-
VectorMA( normal, weight, tmp, normal );
1394+
TransformNormalVector( &bones[ *chunk_modelBlendIndex ], chunk_modelNormal, tmp );
1395+
VectorMA( normal, weight, tmp, normal );
13141396

1315-
TransformNormalVector( &bones[ *modelBlendIndex ], modelTangent, tmp );
1316-
VectorMA( tangent, weight, tmp, tangent );
1397+
TransformNormalVector( &bones[ *chunk_modelBlendIndex ], chunk_modelTangent, tmp );
1398+
VectorMA( tangent, weight, tmp, tangent );
13171399

1318-
TransformNormalVector( &bones[ *modelBlendIndex ], modelBitangent, tmp );
1319-
VectorMA( binormal, weight, tmp, binormal );
1320-
}
1400+
TransformNormalVector( &bones[ *chunk_modelBlendIndex ], chunk_modelBitangent, tmp );
1401+
VectorMA( binormal, weight, tmp, binormal );
1402+
}
13211403

1322-
VectorNormalizeFast( normal );
1323-
VectorNormalizeFast( tangent );
1324-
VectorNormalizeFast( binormal );
1325-
VectorCopy( position, tessVertex->xyz );
1404+
VectorNormalizeFast( normal );
1405+
VectorNormalizeFast( tangent );
1406+
VectorNormalizeFast( binormal );
1407+
VectorCopy( position, chunk_tessVertex->xyz );
13261408

1327-
R_TBNtoQtangentsFast( tangent, binormal, normal, tessVertex->qtangents );
1409+
R_TBNtoQtangentsFast( tangent, binormal, normal, chunk_tessVertex->qtangents );
13281410

1329-
Vector2Copy( modelTexcoord, tessVertex->texCoords );
1330-
}
1411+
Vector2Copy( chunk_modelTexcoord, chunk_tessVertex->texCoords );
1412+
}
1413+
};
1414+
1415+
Omp::Tasker( task, num_chunks );
13311416
}
13321417
}
13331418
else
13341419
{
13351420
float scale = model->internalScale * backEnd.currentEntity->e.skeleton.scale;
13361421

1337-
for ( ; tessVertex < lastVertex; tessVertex++,
1338-
modelPosition += 3, modelNormal += 3,
1339-
modelTangent += 3, modelBitangent += 3,
1340-
modelTexcoord += 2 )
1422+
auto task = [&]( const size_t& chunk_index ) -> void
13411423
{
1342-
VectorScale( modelPosition, scale, tessVertex->xyz );
1424+
size_t chunk_offset = chunk_index * chunk_size;
1425+
1426+
shaderVertex_t *chunk_tessVertex = tessVertex + chunk_offset;
1427+
float *chunk_modelPosition = modelPosition + 3 * chunk_offset;
1428+
float *chunk_modelNormal = modelNormal + 3 * chunk_offset;
1429+
float *chunk_modelTangent = modelTangent + 3 * chunk_offset;
1430+
float *chunk_modelBitangent = modelBitangent + 3 * chunk_offset;
1431+
float *chunk_modelTexcoord = modelTexcoord + 2 * chunk_offset;
1432+
1433+
shaderVertex_t *chunk_lastVertex =
1434+
chunk_index == num_chunks - 1
1435+
? lastVertex
1436+
: chunk_tessVertex + chunk_size;
1437+
1438+
for ( ; chunk_tessVertex < chunk_lastVertex; chunk_tessVertex++,
1439+
chunk_modelPosition += 3, chunk_modelNormal += 3,
1440+
chunk_modelTangent += 3, chunk_modelBitangent += 3,
1441+
chunk_modelTexcoord += 2 )
1442+
{
1443+
VectorScale( chunk_modelPosition, scale, chunk_tessVertex->xyz );
13431444

1344-
R_TBNtoQtangentsFast( modelTangent, modelBitangent, modelNormal, tessVertex->qtangents );
1445+
R_TBNtoQtangentsFast( chunk_modelTangent, chunk_modelBitangent, chunk_modelNormal, chunk_tessVertex->qtangents );
13451446

1346-
Vector2Copy( modelTexcoord, tessVertex->texCoords );
1347-
}
1447+
Vector2Copy( chunk_modelTexcoord, chunk_tessVertex->texCoords );
1448+
}
1449+
};
1450+
1451+
Omp::Tasker( task, num_chunks );
13481452
}
13491453

13501454
tess.numIndexes += numIndexes;

0 commit comments

Comments
 (0)