@@ -161,7 +161,7 @@ void benchFilters(size_t count, double& besto8, double& besto12, double& bestq12
161161 }
162162}
163163
164- void benchMeshlets (const std::vector<float >& positions, const std::vector<unsigned int >& indices, double & bestml, bool verbose)
164+ void benchMeshlets (const std::vector<float >& positions, const std::vector<unsigned int >& indices, bool encoderefs, double & bestml, bool verbose)
165165{
166166 const size_t max_vertices = 64 ;
167167 const size_t max_triangles = 96 ;
@@ -186,28 +186,38 @@ void benchMeshlets(const std::vector<float>& positions, const std::vector<unsign
186186 meshopt_optimizeMeshlet (&meshlet_vertices[meshlets[i].vertex_offset ], &meshlet_triangles[meshlets[i].triangle_offset ], meshlets[i].triangle_count , meshlets[i].vertex_count );
187187
188188 // optimize meshlet_vertices for locality (requires vertex reorder)
189+ // TODO: over-allocate meshlet_vertices to multiple of 3 to make meshopt_optimizeVertexFetch below work without assertions
189190 std::vector<float > positionscopy (positions.size ());
190191 meshlet_vertices.resize ((meshlet_vertices.size () + 2 ) / 3 * 3 );
191192 meshopt_optimizeVertexFetch (&positionscopy[0 ], &meshlet_vertices[0 ], meshlet_vertices.size (), &positions[0 ], positions.size () / 3 , sizeof (float ) * 3 );
192193
194+ #if 0 // TODO: disabled for now to make meshlet decoder tuning more accurate; might make sense to re-enable in the future for SOL timings
195+ // pack meshlets in decreasing triangle count order to reduce branch mispredictions
196+ // (this matters less on real-world meshes but is more prominent on regular grids?)
197+ std::sort(meshlets.begin(), meshlets.end(), [](const meshopt_Meshlet& lhs, const meshopt_Meshlet& rhs)
198+ { return lhs.triangle_count > rhs.triangle_count; });
199+ #endif
200+
193201 std::vector<unsigned char > packed;
194202
195- size_t total_meshlet_data = 0 ;
203+ size_t totals = 0 ;
196204
197205 for (size_t i = 0 ; i < meshlets.size (); ++i)
198206 {
199207 const meshopt_Meshlet& meshlet = meshlets[i];
200208
201- size_t mbs = meshopt_encodeMeshlet (&cbuf[0 ], cbuf.size (), &meshlet_vertices[meshlet.vertex_offset ], meshlet.vertex_count , &meshlet_triangles[meshlet.triangle_offset ], meshlet.triangle_count );
209+ size_t mvc = encoderefs ? meshlet.vertex_count : 0 ;
210+
211+ size_t mbs = meshopt_encodeMeshlet (&cbuf[0 ], cbuf.size (), &meshlet_vertices[meshlet.vertex_offset ], mvc, &meshlet_triangles[meshlet.triangle_offset ], meshlet.triangle_count );
202212 assert (mbs > 0 );
203213
204- packed.push_back (meshlet. vertex_count );
205- packed.push_back (meshlet.triangle_count );
206- packed.push_back (mbs & 0xff );
207- packed.push_back ((mbs >> 8 ) & 0xff );
214+ packed.push_back (( unsigned char )mvc );
215+ packed.push_back (( unsigned char ) meshlet.triangle_count );
216+ packed.push_back (( unsigned char )( mbs & 0xff ) );
217+ packed.push_back ((unsigned char )(( mbs >> 8 ) & 0xff ) );
208218 packed.insert (packed.end (), cbuf.begin (), cbuf.begin () + mbs);
209219
210- total_meshlet_data += size_t (meshlet.triangle_count ) * 3 + size_t (meshlet. vertex_count ) * 4 ;
220+ totals += size_t (meshlet.triangle_count ) * 3 + size_t (mvc ) * 4 ;
211221 }
212222
213223 if (verbose)
@@ -237,9 +247,9 @@ void benchMeshlets(const std::vector<float>& positions, const std::vector<unsign
237247 double t1 = timestamp ();
238248
239249 if (verbose)
240- printf (" meshlet decode: %.2f ms (%.2f GB/sec)\n " , (t1 - t0) * 1000 , double (total_meshlet_data ) / 1e9 / (t1 - t0));
250+ printf (" meshlet decode: %.2f ms (%.2f GB/sec)\n " , (t1 - t0) * 1000 , double (totals ) / 1e9 / (t1 - t0));
241251
242- bestml = std::max (bestml, double (total_meshlet_data ) / 1e9 / (t1 - t0));
252+ bestml = std::max (bestml, double (totals ) / 1e9 / (t1 - t0));
243253 }
244254}
245255
@@ -402,20 +412,21 @@ int main(int argc, char** argv)
402412 }
403413 }
404414
405- printf (" Algorithm :\t vtx\t idx\t mlet\t oct8\t oct12\t quat12\t col8\t col12\t exp\n " );
415+ printf (" Codec :\t vtx\t idx\t mlet\t mletΔ \t oct8\t oct12\t quat12\t col8\t col12\t exp\n " );
406416
407417 for (int l = 0 ; l < (loop ? 100 : 1 ); ++l)
408418 {
409419 double bestvd = 0 , bestid = 0 ;
410420 benchCodecs (vertices, indices, bestvd, bestid, verbose);
411421
412- double bestml = 0 ;
413- benchMeshlets (positions, indices, bestml, verbose);
422+ double bestml = 0 , bestmt = 0 ;
423+ benchMeshlets (positions, indices, /* encoderefs= */ true , bestml, verbose);
424+ benchMeshlets (positions, indices, /* encoderefs= */ false , bestmt, verbose);
414425
415426 double besto8 = 0 , besto12 = 0 , bestq12 = 0 , bestc8 = 0 , bestc12 = 0 , bestexp = 0 ;
416427 benchFilters (8 * N * N, besto8, besto12, bestq12, bestc8, bestc12, bestexp, verbose);
417428
418- printf (" Score ( GB/s): \t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\n " ,
419- bestvd, bestid, bestml, besto8, besto12, bestq12, bestc8, bestc12, bestexp);
429+ printf (" GB/s : \t %.2f \t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\t %.2f\n " ,
430+ bestvd, bestid, bestml, bestmt, besto8, besto12, bestq12, bestc8, bestc12, bestexp);
420431 }
421432}
0 commit comments