diff options
author | Andreas Grois <andi@grois.info> | 2018-03-14 22:39:06 +0100 |
---|---|---|
committer | Andreas Grois <andi@grois.info> | 2018-03-14 22:39:06 +0100 |
commit | a350181f2c15feb072c2edf5d0c41965936f1948 (patch) | |
tree | 8dc57cf5f3c96d12f28b4bdb81e50252091ab0c3 /BuddhaTest/src | |
parent | 627aa610fc93398ac51129096ce8fb30731af341 (diff) |
First commit with compute pausability
Diffstat (limited to 'BuddhaTest/src')
-rw-r--r-- | BuddhaTest/src/BuddhaTest.cpp | 45 | ||||
-rw-r--r-- | BuddhaTest/src/Helpers.cpp | 2 |
2 files changed, 35 insertions, 12 deletions
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;
diff --git a/BuddhaTest/src/Helpers.cpp b/BuddhaTest/src/Helpers.cpp index 3cb786c..5197421 100644 --- a/BuddhaTest/src/Helpers.cpp +++ b/BuddhaTest/src/Helpers.cpp @@ -332,6 +332,7 @@ namespace Helpers {"--globalWorkgroupSizeX", &globalWorkGroupSizeX},
{"--globalWorkgroupSizeY", &globalWorkGroupSizeY},
{"--globalWorkgroupSizeZ", &globalWorkGroupSizeZ},
+ {"--iterationsPerFrame", &iterationsPerFrame},
{"--imageGamma",&pngGamma},
{"--imageColorScale",&pngColorScale},
{"--output", &pngFilename},
@@ -362,6 +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: 1000." << 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;
}
|