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 000000000..31879837e Binary files /dev/null and b/test/fixtures/light_render_benchmark/dLight.dmp differ diff --git a/test/light_render_benchmark.cpp b/test/light_render_benchmark.cpp new file mode 100644 index 000000000..7d7720bbd --- /dev/null +++ b/test/light_render_benchmark.cpp @@ -0,0 +1,64 @@ +#include + +#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