From a350181f2c15feb072c2edf5d0c41965936f1948 Mon Sep 17 00:00:00 2001 From: Andreas Grois Date: Wed, 14 Mar 2018 22:39:06 +0100 Subject: First commit with compute pausability --- BuddhaTest/src/BuddhaTest.cpp | 45 +++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-) (limited to 'BuddhaTest/src/BuddhaTest.cpp') diff --git a/BuddhaTest/src/BuddhaTest.cpp b/BuddhaTest/src/BuddhaTest.cpp index 5d03ad4..fcc76a3 100644 --- a/BuddhaTest/src/BuddhaTest.cpp +++ b/BuddhaTest/src/BuddhaTest.cpp @@ -122,15 +122,27 @@ int main(int argc, char * argv[]) } glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + const uint32_t workersPerFrame = settings.globalWorkGroupSizeX*settings.globalWorkGroupSizeY*settings.globalWorkGroupSizeZ*settings.localWorkgroupSizeX*settings.localWorkgroupSizeY*settings.localWorkgroupSizeZ; + GLuint stateBuffer; + glGenBuffers(1,&stateBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER,stateBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, 4*(4*workersPerFrame+1),nullptr,GL_DYNAMIC_COPY); + glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8,GL_RED,GL_UNSIGNED_INT,nullptr); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, stateBuffer); + uint32_t iterationCount{0}; glUseProgram(ComputeShader); GLint iterationCountUniformHandle = glGetUniformLocation(ComputeShader, "iterationCount"); GLint orbitLengthUniformHandle = glGetUniformLocation(ComputeShader, "orbitLength"); GLint widthUniformComputeHandle = glGetUniformLocation(ComputeShader, "width"); GLint heightUniformComputeHandle = glGetUniformLocation(ComputeShader, "height"); + GLint iterationChangedHandle = glGetUniformLocation(ComputeShader, "iterationChanged"); + GLint iterationsPerDispatchHandle = glGetUniformLocation(ComputeShader, "iterationsPerDispatch"); glUniform3ui(orbitLengthUniformHandle,settings.orbitLengthRed,settings.orbitLengthGreen,settings.orbitLengthBlue); glUniform1ui(widthUniformComputeHandle, settings.imageWidth); glUniform1ui(heightUniformComputeHandle, bufferHeight); + glUniform1ui(iterationChangedHandle,1); + glUniform1ui(iterationsPerDispatchHandle, settings.iterationsPerFrame); glUseProgram(VertexAndFragmentShaders); GLint widthUniformFragmentHandle = glGetUniformLocation(VertexAndFragmentShaders, "width"); @@ -140,29 +152,37 @@ int main(int argc, char * argv[]) glClearColor(0.0f, 0.0f, 0.4f, 0.0f); - //uint32_t iterationsPerFrame = settings.globalWorkGroupSizeX*settings.globalWorkGroupSizeY*settings.globalWorkGroupSizeZ*settings.localWorkgroupSizeX*settings.localWorkgroupSizeY*settings.localWorkgroupSizeZ; - //bool bWarningShown{false}; - /* Loop until the user closes the window */ while (!glfwWindowShouldClose(window)) { - //commented out, as with the new y-decoupling we will get more points in 2D even after we had all integer values for x. - //check if we are "done" - //if(iterationsPerFrame * iterationCount <= iterationsPerFrame && iterationCount > 1 && !bWarningShown) - //{ - // std::cout << "The program covered all possible integer values for starting point computation. Leaving it running will not improve the image any more." << std::endl; - // bWarningShown = true; - //} + //clear first integer in state buffer. That's the "boolean" we use to determine if we should increment iterationCount. + glBindBuffer(GL_SHADER_STORAGE_BUFFER,stateBuffer); + glClearBufferSubData(GL_SHADER_STORAGE_BUFFER,GL_R8,0,4,GL_RED,GL_UNSIGNED_INT,nullptr); //let the compute shader do something glUseProgram(ComputeShader); - //increase iterationCount, which is used for pseudo random generation - glUniform1ui(iterationCountUniformHandle,++iterationCount); + //set iterationCount, which is used for pseudo random generation + glUniform1ui(iterationCountUniformHandle,iterationCount); glDispatchCompute(settings.globalWorkGroupSizeX, settings.globalWorkGroupSizeY, settings.globalWorkGroupSizeZ); //before reading the values in the ssbo, we need a memory barrier: glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); //I hope this is the correct (and only required) bit + //read back first bit of state buffer. If it's zero, increment iterationcount and set glUniform1ui(iterationChangedHandle,1); + //if it's nonzero set glUniform1ui(iterationChangedHandle,0); + glBindBuffer(GL_SHADER_STORAGE_BUFFER,stateBuffer); + uint accumulatedState; + glGetBufferSubData(GL_SHADER_STORAGE_BUFFER,0,4,&accumulatedState); + if(accumulatedState) + { + glUniform1ui(iterationChangedHandle,0); + } + else + { + glUniform1ui(iterationChangedHandle,1); + ++iterationCount; + } + /* Render here */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(VertexAndFragmentShaders); @@ -210,6 +230,7 @@ int main(int argc, char * argv[]) //a bit of cleanup glDeleteBuffers(1,&vertexbuffer); glDeleteBuffers(3,drawBuffer); + glDeleteBuffers(1,&stateBuffer); glfwTerminate(); return 0; -- cgit v1.2.3