From f7909cac2884683c0bfe6fbb0e50375a1f79f615 Mon Sep 17 00:00:00 2001 From: staphen Date: Mon, 30 Jun 2025 21:57:12 -0400 Subject: [PATCH] Add benchmark for Lightmap::build() --- Source/levels/gendung.h | 2 +- test/CMakeLists.txt | 2 + .../light_render_benchmark/dLight.dmp | Bin 0 -> 12544 bytes test/light_render_benchmark.cpp | 64 ++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/light_render_benchmark/dLight.dmp create mode 100644 test/light_render_benchmark.cpp diff --git a/Source/levels/gendung.h b/Source/levels/gendung.h index d8ad32b3f..15c5401b2 100644 --- a/Source/levels/gendung.h +++ b/Source/levels/gendung.h @@ -181,7 +181,7 @@ extern DVL_API_FOR_TEST MICROS DPieceMicros[MAXTILES]; /** Specifies the transparency at each coordinate of the map. */ extern DVL_API_FOR_TEST int8_t dTransVal[MAXDUNX][MAXDUNY]; /** Current realtime lighting. Per tile. */ -extern uint8_t dLight[MAXDUNX][MAXDUNY]; +extern DVL_API_FOR_TEST uint8_t dLight[MAXDUNX][MAXDUNY]; /** Precalculated static lights. dLight uses this as a base before applying lights. Per tile. */ extern uint8_t dPreLight[MAXDUNX][MAXDUNY]; /** Holds various information about dungeon tiles, @see DungeonFlag */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index cfbc160ce..4d72e5921 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -59,6 +59,7 @@ set(benchmarks clx_render_benchmark crawl_benchmark dun_render_benchmark + light_render_benchmark palette_blending_benchmark path_benchmark ) @@ -106,6 +107,7 @@ target_link_dependencies(dun_render_benchmark PRIVATE libdevilutionx_so) target_link_dependencies(file_util_test PRIVATE libdevilutionx_file_util app_fatal_for_testing) target_link_dependencies(format_int_test PRIVATE libdevilutionx_format_int language_for_testing) target_link_dependencies(ini_test PRIVATE libdevilutionx_ini app_fatal_for_testing) +target_link_dependencies(light_render_benchmark PRIVATE libdevilutionx_so) target_link_dependencies(palette_blending_test PRIVATE libdevilutionx_palette_blending DevilutionX::SDL libdevilutionx_strings GTest::gmock app_fatal_for_testing) target_link_dependencies(palette_blending_benchmark PRIVATE libdevilutionx_palette_blending DevilutionX::SDL app_fatal_for_testing) target_link_dependencies(parse_int_test PRIVATE libdevilutionx_parse_int) diff --git a/test/fixtures/light_render_benchmark/dLight.dmp b/test/fixtures/light_render_benchmark/dLight.dmp new file mode 100644 index 0000000000000000000000000000000000000000..31879837edc83e362bde0917f0a4081974594cf9 GIT binary patch literal 12544 zcmeHMiIRgL46RiwqT>Jm?Is*bs9G=%7_ymSwFpBi@4w=Z(Xn$&_NpFaQ0>iNC34x*29ui~SRZ7&wFW7*vPv*>fB z;&bUcT~cWD`BL$*bvR#Ai2XvTaIM2S%P{UldlC63ZdzO@y4GQxWf*s&y@-}-FKydk zTZfGXiHLGAlg_4at1cmx;-A`Rkf_lQ1A0UGRYTig`6Uff?2%Xah1J1)*n|PI+A?$3 zQ$se(054pypNBJM==;$0Sc|cdbk(F`O5?P1|l56 zr2G~p+5ZUWA-h*yRh0wm;T(i8OzgLR?xm4nJ#ZC(gSbOLv>*r?Taex@O>*EF;z2s8 z%4hKez(yfn!icavF!$2X39on*GhT>Be*|;QBMIz;NBH?{bB{;9;l0`KR*xib;E9oc zg85nv{+Za1zH#wxjz4#31_|bRj@($&lwVxsLwcB$Nru^Y{rJDYV{HEPHLtf@-y1zL zT@etB>qGuiR$KotXR|dDpq}N(aA@rfWq{=Ro-;MU`TNun9crjV=jUB{Gfn*tKHrZ4 zNh0y^`TQnHlpa3cj{(Wn#KY%1EKm8lI+X8# + +#include + +#include "engine/render/light_render.hpp" +#include "engine/surface.hpp" +#include "lighting.h" +#include "utils/log.hpp" +#include "utils/paths.h" +#include "utils/sdl_wrap.h" + +namespace devilution { +namespace { + +void BM_BuildLightmap(benchmark::State &state) +{ + std::string benchmarkDataPath = paths::BasePath() + "test/fixtures/light_render_benchmark/dLight.dmp"; + FILE *lightFile = std::fopen(benchmarkDataPath.c_str(), "rb"); + if (lightFile != nullptr) { + std::fread(&dLight[0][0], sizeof(uint8_t), MAXDUNX * MAXDUNY, lightFile); + std::fclose(lightFile); + } + + SDLSurfaceUniquePtr sdl_surface = SDLWrap::CreateRGBSurfaceWithFormat( + /*flags=*/0, /*width=*/640, /*height=*/480, /*depth=*/8, SDL_PIXELFORMAT_INDEX8); + if (sdl_surface == nullptr) { + LogError("Failed to create SDL Surface: {}", SDL_GetError()); + exit(1); + } + Surface out = Surface(sdl_surface.get()); + + Point tilePosition { 48, 44 }; + Point targetBufferPosition { 0, -17 }; + int viewportWidth = 640; + int viewportHeight = 352; + int rows = 25; + int columns = 10; + const uint8_t *outBuffer = out.at(0, 0); + uint16_t outPitch = out.pitch(); + const uint8_t *lightTables = LightTables[0].data(); + size_t lightTableSize = LightTables[0].size(); + + size_t numViewportTiles = rows * columns; + size_t numPixels = viewportWidth * viewportHeight; + size_t numBytesProcessed = 0; + size_t numItemsProcessed = 0; + for (auto _ : state) { + Lightmap lightmap = Lightmap::build(tilePosition, targetBufferPosition, + viewportWidth, viewportHeight, rows, columns, + outBuffer, outPitch, lightTables, lightTableSize); + + uint8_t lightLevel = *lightmap.getLightingAt(outBuffer + outPitch * 120 + 120); + benchmark::DoNotOptimize(lightLevel); + numItemsProcessed += numViewportTiles; + numBytesProcessed += numPixels; + } + state.SetBytesProcessed(numBytesProcessed); + state.SetItemsProcessed(numItemsProcessed); +} + +BENCHMARK(BM_BuildLightmap); + +} // namespace +} // namespace devilution