From 0eaaeb34308b178a57b894e76aaeccee127cf830 Mon Sep 17 00:00:00 2001 From: Morten Nobel-Joergensen Date: Sat, 17 Mar 2018 21:42:50 +0100 Subject: [PATCH] Add heavy 64k benchmark --- em-build.sh | 2 +- include/sre/SDLRenderer.hpp | 2 + src/sre/SDLRenderer.cpp | 6 + test/CMakeLists.txt | 2 +- test/benchmark64k-heavy.cpp | 214 ++++++++++++++++++++++++++++++++++++ 5 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 test/benchmark64k-heavy.cpp diff --git a/em-build.sh b/em-build.sh index 123b103b..82d3ae40 100755 --- a/em-build.sh +++ b/em-build.sh @@ -8,7 +8,7 @@ fi source ${EMSDK}/emsdk_env.sh -for FILENAME in matrix-uniforms custom-mesh-layout-ints multiple-materials multiple-lights imgui-color-test pbr-test custom-mesh-layout-default-values imgui_demo multi-cameras particle-sprite particle-test polygon-offset-example spinning-sphere-cubemap sprite-test static_vertex_attribute texture-test +for FILENAME in benchmark64k-heavy matrix-uniforms custom-mesh-layout-ints multiple-materials multiple-lights imgui-color-test pbr-test custom-mesh-layout-default-values imgui_demo multi-cameras particle-sprite particle-test polygon-offset-example spinning-sphere-cubemap sprite-test static_vertex_attribute texture-test do echo $FILENAME emcc -Iinclude src/imgui/imgui.cpp \ diff --git a/include/sre/SDLRenderer.hpp b/include/sre/SDLRenderer.hpp index 60d4e790..77303dbc 100755 --- a/include/sre/SDLRenderer.hpp +++ b/include/sre/SDLRenderer.hpp @@ -101,6 +101,8 @@ class DllExport SDLRenderer { SDL_Window *getSDLWindow(); // Get a pointer to SDL_Window static SDLRenderer* instance; // Singleton reference to the engine after initialization. + + glm::vec3 getLastFrameStats(); // Returns delta time for last frame wrt event, update and render private: void frame(float deltaTimeSec); Renderer* r; diff --git a/src/sre/SDLRenderer.cpp b/src/sre/SDLRenderer.cpp index a3136261..eafb890e 100755 --- a/src/sre/SDLRenderer.cpp +++ b/src/sre/SDLRenderer.cpp @@ -315,6 +315,12 @@ namespace sre{ return SDLRenderer::InitBuilder(this); } + glm::vec3 SDLRenderer::getLastFrameStats() { + return { + deltaTimeEvent,deltaTimeUpdate,deltaTimeRender + }; + } + SDLRenderer::InitBuilder::~InitBuilder() { build(); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4f3de2c6..c83f0e84 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,5 @@ # List of single-file tests -SET(scr_files matrix-uniforms custom-mesh-layout-ints multiple-materials render-depth spinning-sphere-cubemap particle-test polygon-offset-example multiple-lights particle-sprite sprite-test multi-cameras static_vertex_attribute custom-mesh-layout-default-values imgui_demo texture-test screen-point-to-ray pbr-test gamma primitives-test imgui-color-test) +SET(scr_files benchmark64k-heavy matrix-uniforms custom-mesh-layout-ints multiple-materials render-depth spinning-sphere-cubemap particle-test polygon-offset-example multiple-lights particle-sprite sprite-test multi-cameras static_vertex_attribute custom-mesh-layout-default-values imgui_demo texture-test screen-point-to-ray pbr-test gamma primitives-test imgui-color-test) # Create custom build targets FOREACH(scr_file ${scr_files}) diff --git a/test/benchmark64k-heavy.cpp b/test/benchmark64k-heavy.cpp new file mode 100644 index 00000000..abaf873b --- /dev/null +++ b/test/benchmark64k-heavy.cpp @@ -0,0 +1,214 @@ +#include +#include +#include + +#include "sre/Texture.hpp" +#include "sre/Renderer.hpp" +#include "sre/Material.hpp" +#include "sre/SDLRenderer.hpp" + +#include +#include +#include +#include + +const int BOX_GRID_DIM = 40; +const int BENCHMARK_SIZE = 40; + +using namespace sre; + +float renderTimeGetter(void* data, int offset){ + float* floatData = static_cast(data); + int id = (int)cbrtf((float)offset); + return floatData[id]; +} +// +class Benchmark64KExample { +public: + Benchmark64KExample() { + r.init(); + + camera = new Camera(); + camera->setPerspectiveProjection(60,0.1,100); + + worldLights.addLight(Light::create().withDirectionalLight(glm::vec3(1,1,1)).withColor(Color(1,1,1),1).build()); + renderTime.resize(BOX_GRID_DIM+1,0); + stateChanges.resize(BOX_GRID_DIM+1,0); + drawCalls.resize(BOX_GRID_DIM+1,0); + meshes = { + Mesh::create().withCube(0.25f).build(), + Mesh::create().withSphere().build(), + Mesh::create().withTorus().build(), + Mesh::create().withQuad().build(), + Mesh::create().withCube(0.35f).build(), + }; + + + materials = { + Shader::getUnlit()->createMaterial(), + Shader::getStandardBlinnPhong()->createMaterial(), + Shader::getStandardPBR()->createMaterial(), + Shader::getUnlit()->createMaterial(), + Shader::getStandardBlinnPhong()->createMaterial(), + Shader::getStandardPBR()->createMaterial(), + Shader::getUnlit()->createMaterial(), + }; + + for (int i = 0;isetTexture(Texture::create().withFile("examples_data/test.png").withGenerateMipmaps(true).build()); + } else { + materials[i]->setTexture(Texture::create().withFile("examples_data/cartman.png").withGenerateMipmaps(true).build()); + } + } + + int boxI = 0; + float offset = -(gridSize / 2.0f); + for (int i = 0; i < BOX_GRID_DIM; ++i) { + for (int j = 0; j < BOX_GRID_DIM; ++j) { + for (int k = 0; k < BOX_GRID_DIM; ++k) { + box[i][j][k] = { + glm::rotate((float) (boxI / M_PI), glm::vec3(1,1,1)), + glm::translate(glm::vec3(i + offset, j + offset, k + offset)) + }; + boxI++; + } + } + } + r.frameUpdate = [&](float delta){ + update(delta); + }; + r.frameRender = [&](){ + render(); + }; + + r.startEventLoop(); + } + void update(float delta){ + static float totalTime = 0; + eyeRotation += 0.002; + eyePosition[0] = (float) (sin(eyeRotation) * eyeRadius); + eyePosition[2] = (float) (cos(eyeRotation) * eyeRadius); + if (cameraInCenter){ + camera->lookAt( {0, 0, 0}, glm::normalize(eyePosition),{0, 1, 0}); + } else { + camera->lookAt(eyePosition, {0, 0, 0}, {0, 1, 0}); + } + totalTime += delta; + for (int i = 0; i < gridSize; ++i) { + for (int j = 0; j < gridSize; ++j) { + for (int k = 0; k < gridSize; ++k) { + auto & boxRef = box[i][j][k]; + // update rotation + boxRef.rotationMatrix = glm::rotate(glm::mat4(1),0.02f*totalTime, glm::vec3(0,1,0)); + modelMatrix[i][j][k] = boxRef.translationMatrix * boxRef.rotationMatrix; + } + } + } + } + + void render(){ + if (benchmarkCount >=0){ + if (benchmarkCount>0 && benchmarkCount-1 < renderTime.size()){ + //Renderer::instance->getRenderStats().drawCalls; + renderTime[benchmarkCount-1] = SDLRenderer::instance->getLastFrameStats().z; + stateChanges[benchmarkCount-1] = Renderer::instance->getRenderStats().stateChangesMaterial + Renderer::instance->getRenderStats().stateChangesShader + Renderer::instance->getRenderStats().stateChangesMesh; + drawCalls[benchmarkCount-1] = Renderer::instance->getRenderStats().drawCalls; + } + if (benchmarkCount+1 == BOX_GRID_DIM){ + benchmarkCount = -1; + gridSize = BOX_GRID_DIM/3; + } else { + benchmarkCount++; + gridSize = benchmarkCount; + } + + } + auto renderPass = RenderPass::create() + .withCamera(*camera) + .withWorldLights(&worldLights) + .withClearColor(true, {0, 0, 0, 1}) + .build(); + int id=0; + for (int i = 0; i < gridSize; ++i) { + for (int j = 0; j < gridSize; ++j) { + for (int k = 0; k < gridSize; ++k) { + renderPass.draw(meshes[id%meshes.size()], modelMatrix[i][j][k], materials[id%materials.size()]); + id++; + } + } + } + i++; + static Inspector inspector; + inspector.update(); + + bool gridChanged = ImGui::SliderInt("Grid size",&gridSize,1,BOX_GRID_DIM); + if (gridChanged){ + float offset = -(gridSize / 2.0f); + for (int i = 0; i < gridSize; ++i) { + for (int j = 0; j < gridSize; ++j) { + for (int k = 0; k < gridSize; ++k) { + auto & boxRef = box[i][j][k]; + // update rotation + boxRef.translationMatrix = glm::translate(glm::vec3(i + offset, j + offset, k + offset)); + } + } + } + + } + ImGui::Checkbox("Camera in center",&cameraInCenter); + + if (benchmarkCount >= 0){ + ImGui::LabelText("","Benchmark running"); + } else { + if (ImGui::Button("Start benchmark")){ + benchmarkCount = 1; + for (auto & v : renderTime){ + v = 0; + } + for (auto &v : stateChanges){ + v = 0; + } + for (auto &v : drawCalls){ + v = 0; + } + + } + } + + + ImGui::PlotLines("Objects/Render time",&renderTimeGetter,renderTime.data(),(BENCHMARK_SIZE-1)*(BENCHMARK_SIZE-1)*(BENCHMARK_SIZE-1), 0, "Render time", FLT_MAX,FLT_MAX,ImVec2(ImGui::CalcItemWidth(),150)); + ImGui::PlotLines("Objects/State changes",&renderTimeGetter,stateChanges.data(),(BENCHMARK_SIZE-1)*(BENCHMARK_SIZE-1)*(BENCHMARK_SIZE-1), 0, "State changes", FLT_MAX,FLT_MAX,ImVec2(ImGui::CalcItemWidth(),150)); + ImGui::PlotLines("Objects/Draw calls",&renderTimeGetter,drawCalls.data(),(BENCHMARK_SIZE-1)*(BENCHMARK_SIZE-1)*(BENCHMARK_SIZE-1), 0, "Draw calls", FLT_MAX,FLT_MAX,ImVec2(ImGui::CalcItemWidth(),150)); + inspector.gui(); + + } +private: + int gridSize = BOX_GRID_DIM/2; + float eyeRadius = 30; + float eyeRotation = 0; + glm::vec3 eyePosition = {0, eyeRadius, 0}; + bool cameraInCenter = false; + SDLRenderer r; + Camera *camera; + WorldLights worldLights; + std::vector> meshes; + std::vector> materials; + std::vector renderTime; + std::vector stateChanges; + std::vector drawCalls; + int benchmarkCount = -1; + int i=0; + struct Box{ + glm::mat4 rotationMatrix; + glm::mat4 translationMatrix; + } box[BOX_GRID_DIM][BOX_GRID_DIM][BOX_GRID_DIM]; + glm::mat4 modelMatrix[BOX_GRID_DIM][BOX_GRID_DIM][BOX_GRID_DIM]; + +}; + +int main() { + new Benchmark64KExample(); + return 0; +}