From 32f2b1fbb6971c3f241df64dda2b3c8977b74485 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Sat, 6 Sep 2025 13:10:44 +0800 Subject: [PATCH] [Feat] (MG_Benchmark/BufferBench): Implement BufferBench. --- MobileGL/MG_Benchmark/Buffer/BufferBench.cpp | 191 +++++++++++++++++++ MobileGL/MG_Benchmark/Buffer/CMakeLists.txt | 19 ++ MobileGL/MG_Benchmark/CMakeLists.txt | 3 +- 3 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 MobileGL/MG_Benchmark/Buffer/BufferBench.cpp create mode 100644 MobileGL/MG_Benchmark/Buffer/CMakeLists.txt diff --git a/MobileGL/MG_Benchmark/Buffer/BufferBench.cpp b/MobileGL/MG_Benchmark/Buffer/BufferBench.cpp new file mode 100644 index 00000000..c3bc11f7 --- /dev/null +++ b/MobileGL/MG_Benchmark/Buffer/BufferBench.cpp @@ -0,0 +1,191 @@ +#include +#include +#include + +#include "MG_Impl/GLImpl/Buffer/GL_Buffer.h" +#include "MG_State/GLState/Core.h" + +using namespace MobileGL; +using namespace MobileGL::MG_Impl::GLImpl; + +constexpr GLuint BUFFER_COUNT = 32; +constexpr GLsizeiptr BUFFER_SIZE = 1024 * 1024; + +static void BM_GenerateAndDeleteBuffers(benchmark::State& state) { + MG_State::pGLContext = new MG_State::GLState::GLContext(); + + GLuint n = static_cast(state.range(0)); + int repeat = static_cast(state.range(1)); + std::vector buffers(n); + + for (auto _ : state) { + for (int i = 0; i < repeat; i++) { + GenBuffers(n, buffers.data()); + DeleteBuffers(n, buffers.data()); + } + } + + state.SetItemsProcessed(state.iterations() * repeat * n); + delete MG_State::pGLContext; +} + +BENCHMARK(BM_GenerateAndDeleteBuffers) + ->Args({128, 5}) + ->Args({1024, 10}) + ->Args({1536, 16}) + ->Args({2048, 32}) + ->Unit(benchmark::kMillisecond) + ->UseRealTime(); + +static void BM_CreateBufferObjectsAndBindBuffer(benchmark::State& state) { + MG_State::pGLContext = new MG_State::GLState::GLContext(); + + GLuint buffers[BUFFER_COUNT]; + GenBuffers(BUFFER_COUNT, buffers); + + for (auto _ : state) { + for (GLuint i = 0; i < BUFFER_COUNT; i++) { + GLenum target = (i % 2 == 0) ? GL_ARRAY_BUFFER : GL_UNIFORM_BUFFER; + BindBuffer(target, buffers[i]); + } + } + + state.SetItemsProcessed(state.iterations() * BUFFER_COUNT); + + DeleteBuffers(BUFFER_COUNT, buffers); + delete MG_State::pGLContext; +} +BENCHMARK(BM_CreateBufferObjectsAndBindBuffer)->Unit(benchmark::kMillisecond)->UseRealTime(); + +static void BM_DeleteBufferObjects(benchmark::State& state) { + MG_State::pGLContext = new MG_State::GLState::GLContext(); + std::vector buffers(BUFFER_COUNT); + + for (auto _ : state) { + state.PauseTiming(); + GenBuffers(BUFFER_COUNT, buffers.data()); + for (GLuint i = 0; i < BUFFER_COUNT; i++) { + GLenum target = (i % 2 == 0) ? GL_ARRAY_BUFFER : GL_UNIFORM_BUFFER; + BindBuffer(target, buffers[i]); + } + state.ResumeTiming(); + + DeleteBuffers(BUFFER_COUNT, buffers.data()); + } + + state.SetItemsProcessed(state.iterations() * BUFFER_COUNT); + delete MG_State::pGLContext; +} +BENCHMARK(BM_DeleteBufferObjects)->Unit(benchmark::kMillisecond)->UseRealTime(); + +static void BM_UpdateData(benchmark::State& state) { + MG_State::pGLContext = new MG_State::GLState::GLContext(); + + GLuint buffers[BUFFER_COUNT]; + GenBuffers(BUFFER_COUNT, buffers); + + for (GLuint i = 0; i < BUFFER_COUNT; i++) + BindBuffer(GL_ARRAY_BUFFER, buffers[i]); + + std::vector data(BUFFER_SIZE, 0); + + for (auto _ : state) { + for (GLuint i = 0; i < BUFFER_COUNT; i++) { + BindBuffer(GL_ARRAY_BUFFER, buffers[i]); + BufferData(GL_ARRAY_BUFFER, BUFFER_SIZE, data.data(), GL_STATIC_DRAW); + } + } + + state.SetItemsProcessed(state.iterations() * BUFFER_COUNT); + + DeleteBuffers(BUFFER_COUNT, buffers); + delete MG_State::pGLContext; +} +BENCHMARK(BM_UpdateData)->Unit(benchmark::kMillisecond)->UseRealTime(); + +static void BM_MapBuffer(benchmark::State& state) { + MG_State::pGLContext = new MG_State::GLState::GLContext(); + + GLuint buffers[BUFFER_COUNT]; + GenBuffers(BUFFER_COUNT, buffers); + for (GLuint i = 0; i < BUFFER_COUNT; i++) + BindBuffer(GL_ARRAY_BUFFER, buffers[i]); + + std::vector data(BUFFER_SIZE, 0); + + for (auto _ : state) { + for (GLuint i = 0; i < BUFFER_COUNT; i++) { + BindBuffer(GL_ARRAY_BUFFER, buffers[i]); + BufferData(GL_ARRAY_BUFFER, BUFFER_SIZE, data.data(), GL_DYNAMIC_DRAW); + + void* ptr = MapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + if (ptr) { + memset(ptr, 1, BUFFER_SIZE); + UnmapBuffer(GL_ARRAY_BUFFER); + } + } + } + + state.SetItemsProcessed(state.iterations() * BUFFER_COUNT); + + DeleteBuffers(BUFFER_COUNT, buffers); + delete MG_State::pGLContext; +} +BENCHMARK(BM_MapBuffer)->Unit(benchmark::kMillisecond)->UseRealTime(); + +static void BM_CopyBufferSubData(benchmark::State& state) { + MG_State::pGLContext = new MG_State::GLState::GLContext(); + + GLuint buffers[BUFFER_COUNT]; + GenBuffers(BUFFER_COUNT, buffers); + + std::vector data(BUFFER_SIZE, 0); + + for (GLuint i = 0; i < BUFFER_COUNT; i++) { + GLenum target = (i % 2 == 0) ? GL_COPY_READ_BUFFER : GL_COPY_WRITE_BUFFER; + BindBuffer(target, buffers[i]); + BufferData(target, BUFFER_SIZE, data.data(), GL_STATIC_DRAW); + } + + for (auto _ : state) { + for (GLuint i = 0; i < BUFFER_COUNT; i += 2) { + BindBuffer(GL_COPY_READ_BUFFER, buffers[i]); + BindBuffer(GL_COPY_WRITE_BUFFER, buffers[i + 1]); + CopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, BUFFER_SIZE); + } + } + + state.SetItemsProcessed(state.iterations() * (BUFFER_COUNT / 2)); + + DeleteBuffers(BUFFER_COUNT, buffers); + delete MG_State::pGLContext; +} +BENCHMARK(BM_CopyBufferSubData)->Unit(benchmark::kMillisecond)->UseRealTime(); + +static void BM_UpdateDataPartially(benchmark::State& state) { + MG_State::pGLContext = new MG_State::GLState::GLContext(); + + std::vector buffers(BUFFER_COUNT); + std::vector data(BUFFER_SIZE / 10, 1); + + GenBuffers(BUFFER_COUNT, buffers.data()); + for (GLuint i = 0; i < BUFFER_COUNT; i++) { + BindBuffer(GL_ARRAY_BUFFER, buffers[i]); + BufferData(GL_ARRAY_BUFFER, BUFFER_SIZE, nullptr, GL_DYNAMIC_DRAW); + } + + for (auto _ : state) { + for (GLuint i = 0; i < BUFFER_COUNT; i++) { + BindBuffer(GL_ARRAY_BUFFER, buffers[i]); + BufferSubData(GL_ARRAY_BUFFER, BUFFER_SIZE / 2, data.size(), data.data()); + } + } + + state.SetItemsProcessed(state.iterations() * BUFFER_COUNT); + + DeleteBuffers(BUFFER_COUNT, buffers.data()); + delete MG_State::pGLContext; +} +BENCHMARK(BM_UpdateDataPartially)->Unit(benchmark::kMillisecond)->UseRealTime(); + +BENCHMARK_MAIN(); diff --git a/MobileGL/MG_Benchmark/Buffer/CMakeLists.txt b/MobileGL/MG_Benchmark/Buffer/CMakeLists.txt new file mode 100644 index 00000000..35a2d983 --- /dev/null +++ b/MobileGL/MG_Benchmark/Buffer/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.24) + +add_executable( + BufferBench + BufferBench.cpp +) + +target_include_directories(BufferBench PRIVATE + ${MGL_ROOT}/include + ${MGL_ROOT}/MobileGL +) + +target_link_libraries( + BufferBench PRIVATE + benchmark::benchmark + ${LINK_LIBRARIES} +) + +add_test(NAME BufferBench COMMAND BufferBench --benchmark_counters_tabular=true) \ No newline at end of file diff --git a/MobileGL/MG_Benchmark/CMakeLists.txt b/MobileGL/MG_Benchmark/CMakeLists.txt index 1067b219..6015aae6 100644 --- a/MobileGL/MG_Benchmark/CMakeLists.txt +++ b/MobileGL/MG_Benchmark/CMakeLists.txt @@ -39,4 +39,5 @@ target_link_libraries( add_test(NAME SanityBench COMMAND SanityBench --benchmark_counters_tabular=true) -add_subdirectory(Program) \ No newline at end of file +add_subdirectory(Program) +add_subdirectory(Buffer) \ No newline at end of file