From bb9b7d23a1ca8e2afa8c8636d7312adc700d9a34 Mon Sep 17 00:00:00 2001 From: Andreas Grois Date: Thu, 15 Mar 2018 22:34:52 +0100 Subject: Fix endless loop in shader and make framerate adaptive It seems forcing points outside the cardioid and bulb with a bad random generator can take really long... Also, now framerate adjusts based on time it takes to render frames. --- BuddhaTest/src/BuddhaTest.cpp | 21 +++++++++++++++++++-- BuddhaTest/src/Helpers.cpp | 4 ++-- 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'BuddhaTest/src') diff --git a/BuddhaTest/src/BuddhaTest.cpp b/BuddhaTest/src/BuddhaTest.cpp index 67971ea..88f9c9b 100644 --- a/BuddhaTest/src/BuddhaTest.cpp +++ b/BuddhaTest/src/BuddhaTest.cpp @@ -3,6 +3,7 @@ #include #include #include +#include void error_callback(int error, const char* description) { @@ -138,21 +139,26 @@ int main(int argc, char * argv[]) glUniform3ui(orbitLengthUniformHandle,settings.orbitLengthRed,settings.orbitLengthGreen,settings.orbitLengthBlue); glUniform1ui(widthUniformComputeHandle, settings.imageWidth); glUniform1ui(heightUniformComputeHandle, bufferHeight); - glUniform1ui(iterationsPerDispatchHandle, settings.iterationsPerFrame); glUseProgram(VertexAndFragmentShaders); GLint widthUniformFragmentHandle = glGetUniformLocation(VertexAndFragmentShaders, "width"); GLint heightUniformFragmentHandle = glGetUniformLocation(VertexAndFragmentShaders, "height"); glUniform1ui(widthUniformFragmentHandle, settings.imageWidth); glUniform1ui(heightUniformFragmentHandle, bufferHeight); - glClearColor(0.0f, 0.0f, 0.4f, 0.0f); + uint32_t iterationsPerFrame = 1; + + Helpers::PIDController pid{0.0f,0.0f,1e-6f}; + const uint32_t targetFrameDuration{1000000/settings.targetFrameRate}; + /* Loop until the user closes the window */ while (!glfwWindowShouldClose(window)) { + auto frameStart{std::chrono::high_resolution_clock::now()}; //let the compute shader do something glUseProgram(ComputeShader); + glUniform1ui(iterationsPerDispatchHandle, iterationsPerFrame); glDispatchCompute(settings.globalWorkGroupSizeX, settings.globalWorkGroupSizeY, settings.globalWorkGroupSizeZ); //before reading the values in the ssbo, we need a memory barrier: @@ -181,6 +187,17 @@ int main(int argc, char * argv[]) /* Poll for and process events */ glfwPollEvents(); + auto frameStop{std::chrono::high_resolution_clock::now()}; + const auto dur{std::chrono::duration_cast(frameStop-frameStart)}; + auto frameDuration{dur.count()}; + if(frameDuration > 0) + { + const auto error{targetFrameDuration - frameDuration}; + const auto pidOutput{pid.Update(frameDuration,error)}; + iterationsPerFrame = std::max(1,static_cast(pidOutput)); + + //std::cout << iterationsPerFrame << " " << pidOutput << std::endl; + } } if(!settings.pngFilename.empty()) diff --git a/BuddhaTest/src/Helpers.cpp b/BuddhaTest/src/Helpers.cpp index 02cc309..94c21a9 100644 --- a/BuddhaTest/src/Helpers.cpp +++ b/BuddhaTest/src/Helpers.cpp @@ -332,7 +332,7 @@ namespace Helpers {"--globalWorkgroupSizeX", &globalWorkGroupSizeX}, {"--globalWorkgroupSizeY", &globalWorkGroupSizeY}, {"--globalWorkgroupSizeZ", &globalWorkGroupSizeZ}, - {"--iterationsPerFrame", &iterationsPerFrame}, + {"--targetFrameRate", &targetFrameRate}, {"--imageGamma",&pngGamma}, {"--imageColorScale",&pngColorScale}, {"--output", &pngFilename}, @@ -363,7 +363,7 @@ namespace Helpers "--globalWorkgroupSizeX [integer] : How often the local work group should be invoked per frame. Values up to 65535 are guaranteed to work. Default is 1024." << std::endl << "--globalWorkgroupSizeY [integer] : How often the local work group should be invoked per frame. Values up to 65535 are guaranteed to work. Default is 1." << std::endl << "--globalWorkgroupSizeZ [integer] : How often the local work group should be invoked per frame. Values up to 65535 are guaranteed to work. Default is 1." << std::endl << - "--iterationsPerFrame [integer] : Limit how many iteration steps the shader may make per frame. Use this to keep the desktop responsive while rendering high iteration count images. Default: 10." << std::endl << + "--targetFrameRate [integer] : The number of iterations per frame will dynamically adjust to approximately reach this framerate. Default: 60." << std::endl << "--ignoreMaxBufferSize [0,1] : If set to 1, a failed maximum buffer size check is not treated as error. Some graphics drivers report lower values than their absolute limit. Do this on your own risk, though." << std::endl; return false; } -- cgit v1.2.3