From dc193156a82a80cc8d2321cf065019035855516f Mon Sep 17 00:00:00 2001 From: Andreas Grois Date: Sun, 18 Mar 2018 21:11:39 +0100 Subject: Undo splitting of buffers in three. Makes buffer access much faster Not kidding here. For the default parameters this increased the maximum pixel brightness in the image by a factor of 2.25. This has the drawback that the maximum possible image size got reduced, but hey, there's a command line switch to ignore all size limits ;-) --- BuddhaTest/Shaders/BuddhaCompute.glsl | 18 +++++------------ BuddhaTest/Shaders/BuddhaFragment.glsl | 14 +++---------- BuddhaTest/src/BuddhaTest.cpp | 36 +++++++++++----------------------- BuddhaTest/src/Helpers.cpp | 4 ++-- 4 files changed, 21 insertions(+), 51 deletions(-) diff --git a/BuddhaTest/Shaders/BuddhaCompute.glsl b/BuddhaTest/Shaders/BuddhaCompute.glsl index 7cd4efe..caf10ee 100644 --- a/BuddhaTest/Shaders/BuddhaCompute.glsl +++ b/BuddhaTest/Shaders/BuddhaCompute.glsl @@ -4,15 +4,7 @@ layout(std430, binding=2) restrict buffer renderedDataRed { - restrict uint counts_SSBORed[]; -}; -layout(std430, binding=3) restrict buffer renderedDataGreen -{ - restrict uint counts_SSBOGreen[]; -}; -layout(std430, binding=4) restrict buffer renderedDataBlue -{ - restrict uint counts_SSBOBlue[]; + restrict uint counts_SSBO[]; }; struct individualData @@ -38,10 +30,10 @@ uniform uint totalIterations; void addToColorOfCell(uvec2 cell, uvec3 toAdd) { - uint firstIndex = (cell.x + cell.y * width); - atomicAdd(counts_SSBORed[firstIndex],toAdd.x); - atomicAdd(counts_SSBOGreen[firstIndex],toAdd.y); - atomicAdd(counts_SSBOBlue[firstIndex],toAdd.z); + uint firstIndex = 3*(cell.x + cell.y * width); + atomicAdd(counts_SSBO[firstIndex],toAdd.x); + atomicAdd(counts_SSBO[firstIndex+1],toAdd.y); + atomicAdd(counts_SSBO[firstIndex+2],toAdd.z); } uvec2 getCell(vec2 complex) diff --git a/BuddhaTest/Shaders/BuddhaFragment.glsl b/BuddhaTest/Shaders/BuddhaFragment.glsl index b33ee1d..449aa29 100644 --- a/BuddhaTest/Shaders/BuddhaFragment.glsl +++ b/BuddhaTest/Shaders/BuddhaFragment.glsl @@ -6,15 +6,7 @@ out vec3 color; layout(std430, binding=2) restrict readonly buffer renderedDataRed { - restrict readonly uint counts_SSBORed[]; -}; -layout(std430, binding=3) restrict readonly buffer renderedDataGreen -{ - restrict readonly uint counts_SSBOGreen[]; -}; -layout(std430, binding=4) restrict readonly buffer renderedDataBlue -{ - restrict readonly uint counts_SSBOBlue[]; + restrict readonly uint counts_SSBO[]; }; uniform uint width; @@ -24,8 +16,8 @@ uvec3 getColorAt(vec2 fragCoord) { uint xIndex = uint(max(0.0,(fragCoord.x+1.0)*0.5*width)); uint yIndex = uint(max(0.0,abs(fragCoord.y)*height)); - uint firstIndex = (xIndex + yIndex * width); - return uvec3(counts_SSBORed[firstIndex],counts_SSBOGreen[firstIndex],counts_SSBOBlue[firstIndex]); + uint firstIndex = 3*(xIndex + yIndex * width); + return uvec3(counts_SSBO[firstIndex],counts_SSBO[firstIndex+1],counts_SSBO[firstIndex+2]); } void main(){ diff --git a/BuddhaTest/src/BuddhaTest.cpp b/BuddhaTest/src/BuddhaTest.cpp index 0a99fee..c1f054d 100644 --- a/BuddhaTest/src/BuddhaTest.cpp +++ b/BuddhaTest/src/BuddhaTest.cpp @@ -112,17 +112,12 @@ int main(int argc, char * argv[]) glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); - GLuint drawBuffer[3]; - glGenBuffers(3, drawBuffer); - for(int i=0; i < 3; ++i) - { - glBindBuffer(GL_SHADER_STORAGE_BUFFER, drawBuffer[i]); - { - glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * pixelCount, nullptr, GL_DYNAMIC_COPY); - glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8,GL_RED,GL_UNSIGNED_INT,nullptr); - } - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2+i, drawBuffer[i]); - } + GLuint drawBuffer; + glGenBuffers(1, &drawBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, drawBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, 4 *3* pixelCount, nullptr, GL_DYNAMIC_COPY); + glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8,GL_RED,GL_UNSIGNED_INT,nullptr); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, drawBuffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); //the state buffer is special. While making each entry 8 bytes large and using std430 layout, the data is never read back, @@ -235,25 +230,16 @@ int main(int argc, char * argv[]) if(!settings.pngFilename.empty()) { glMemoryBarrier(GL_ALL_BARRIER_BITS); - std::vector> readBackBuffers(3,std::vector(pixelCount)); - for(int i = 0; i < 3; ++i) - { - glBindBuffer(GL_SHADER_STORAGE_BUFFER, drawBuffer[i]); - glGetBufferSubData(GL_SHADER_STORAGE_BUFFER,0,4 * pixelCount,readBackBuffers[i].data()); - } + std::vector readBackBuffer(pixelCount*3); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, drawBuffer); + glGetBufferSubData(GL_SHADER_STORAGE_BUFFER,0,4 *3* pixelCount,readBackBuffer.data()); - //too lazy to change WriteOutputPng... - std::vector combinedBuffer(3*pixelCount); - for(uint32_t i=0;i<3*pixelCount;++i) - { - combinedBuffer[i] = readBackBuffers[i%3][i/3]; - } - Helpers::WriteOutputPNG(settings.pngFilename,combinedBuffer,settings.imageWidth,bufferHeight, settings.pngGamma, settings.pngColorScale); + Helpers::WriteOutputPNG(settings.pngFilename,readBackBuffer,settings.imageWidth,bufferHeight, settings.pngGamma, settings.pngColorScale); } //a bit of cleanup glDeleteBuffers(1,&vertexbuffer); - glDeleteBuffers(3,drawBuffer); + glDeleteBuffers(1,&drawBuffer); glDeleteBuffers(1,&stateBuffer); glfwTerminate(); diff --git a/BuddhaTest/src/Helpers.cpp b/BuddhaTest/src/Helpers.cpp index e499f0c..2a687d2 100644 --- a/BuddhaTest/src/Helpers.cpp +++ b/BuddhaTest/src/Helpers.cpp @@ -264,9 +264,9 @@ namespace Helpers } int maxSSBOSize; glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE,&maxSSBOSize); - if((static_cast(imageWidth) * static_cast(imageHeight)) > static_cast(maxSSBOSize)/2) //divided by 2, as we have 4 bytes per int, but only half the image height + if((static_cast(imageWidth) * static_cast(imageHeight)) > static_cast(maxSSBOSize)/6) //divided by 3*2, as we have three colors per pixel, 4 bytes per int, but only half the image height { - std::cerr << "Requested buffer size is larger than maximum allowed by graphics driver. Max pixel number: " << maxSSBOSize/2 << std::endl; + std::cerr << "Requested buffer size is larger than maximum allowed by graphics driver. Max pixel number: " << maxSSBOSize/6 << std::endl; std::cerr << "You can override this limit check using the --ignoreMaxBufferSize 1 command line parameter, but doing so is your own risk." << std::endl; if(ignoreMaxBufferSize == 0) return false; -- cgit v1.2.3