diff --git a/src/FrameBuffer.cpp b/src/FrameBuffer.cpp index f616203..88fdeaf 100644 --- a/src/FrameBuffer.cpp +++ b/src/FrameBuffer.cpp @@ -34,6 +34,11 @@ #define FRAMEBUFFER_DEBUG #endif +ulong FrameBuffer::total_mem_usage = 0; +ulong FrameBuffer::memory_usage() +{ + return total_mem_usage; +} FrameBuffer::FrameBuffer(glm::vec3 resolution, FrameBufferFlags flags): flags_(flags), textureid_(0), multisampling_textureid_(0), framebufferid_(0), multisampling_framebufferid_(0), mem_usage_(0) @@ -71,7 +76,7 @@ void FrameBuffer::init() } // calculate GPU memory usage (for debug only) - mem_usage_ += ( attrib_.viewport.x * attrib_.viewport.y * (flags_ & FrameBuffer_alpha?4:3) ) / 1024; + mem_usage_ += ( attrib_.viewport.x * attrib_.viewport.y * (flags_ & FrameBuffer_alpha?4:3) ); // common texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -113,7 +118,7 @@ void FrameBuffer::init() glBindFramebuffer(GL_FRAMEBUFFER, multisampling_framebufferid_); // calculate GPU memory usage - mem_usage_ += ( Settings::application.render.multisampling * attrib_.viewport.x * attrib_.viewport.y * (flags_ & FrameBuffer_alpha?4:3) ) / 1024; + mem_usage_ += ( Settings::application.render.multisampling * attrib_.viewport.x * attrib_.viewport.y * (flags_ & FrameBuffer_alpha?4:3) ); #ifdef FRAMEBUFFER_DEBUG g_printerr("multi sampling (%d) - ", Settings::application.render.multisampling); @@ -133,18 +138,20 @@ void FrameBuffer::init() for(int i=1; i < MIPMAP_LEVEL; ++i) { width = MAX(1, (width / 2)); height = MAX(1, (height / 2)); - mem_usage_ += ( width * height * (flags_ & FrameBuffer_alpha?4:3) ) / 1024; + mem_usage_ += ( width * height * (flags_ & FrameBuffer_alpha?4:3) ); } #ifdef FRAMEBUFFER_DEBUG g_printerr("mipmap (%d) - ", MIPMAP_LEVEL); #endif } + total_mem_usage += mem_usage_; + if ( !checkFramebufferStatus() ) reset(); #ifdef FRAMEBUFFER_DEBUG else - g_printerr("~%d kB allocated\n", mem_usage_); + g_printerr("~%lu Bytes allocated (%lu kB total)\n", mem_usage_, total_mem_usage / 1000); #endif glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -152,8 +159,11 @@ void FrameBuffer::init() FrameBuffer::~FrameBuffer() { + total_mem_usage -= mem_usage_; + #ifdef FRAMEBUFFER_DEBUG - g_printerr("Framebuffer %d deleted - ~%d kB freed\n", framebufferid_, mem_usage_); + if (framebufferid_) + g_printerr("Framebuffer %d deleted - ~%lu B freed (%lu kB total)\n", framebufferid_, mem_usage_, total_mem_usage / 1000); #endif reset(); @@ -361,17 +371,18 @@ bool FrameBuffer::checkFramebufferStatus() { // success ret = true; - // test available memory if created buffer is big (more than 8MB) - if ( mem_usage_ > 8000 ) { + // test available memory if created buffer is big (more than 20 MByte) + if ( mem_usage_ > (20000000) ) { // Obtain RAM usage in GPU (if possible) glm::ivec2 RAM = Rendering::getGPUMemoryInformation(); - // bad case: not enough RAM, we should warn the user - if ( uint(RAM.x) < mem_usage_ * 3 ) { - Log::Warning("Critical allocation of frame buffer: only %d kB RAM remaining in graphics card.", RAM.x ); + // bad case: not enough RAM, we should warn the user (testing values in KByte, for twice needed space) + if ( uint(RAM.x) < mem_usage_ / 2000 ) { + Log::Warning("Critical allocation of frame buffer: only %d kB RAM in " + "graphics card to allocate %lu framebuffer.", RAM.x, mem_usage_ / 1000); if (RAM.y < INT_MAX) - Log::Warning("Only %.1f %% of %d kB available.", 100.f*float(RAM.x)/float(RAM.y), RAM.y); + Log::Warning("Only %.1f %% of %d kB GPU RAM available.", 100.f*float(RAM.x)/float(RAM.y), RAM.y); } } } diff --git a/src/FrameBuffer.h b/src/FrameBuffer.h index c072b5d..c4aec6d 100644 --- a/src/FrameBuffer.h +++ b/src/FrameBuffer.h @@ -95,6 +95,9 @@ public: FrameBufferImage *image(); bool fill(FrameBufferImage *image); + // how much memory used, in Bytes + static ulong memory_usage(); + private: void init(); void reset(); @@ -106,7 +109,8 @@ private: glm::vec4 projection_area_; uint textureid_, multisampling_textureid_; uint framebufferid_, multisampling_framebufferid_; - uint mem_usage_; + ulong mem_usage_; + static ulong total_mem_usage; }; diff --git a/src/UserInterfaceManager.cpp b/src/UserInterfaceManager.cpp index 2758aab..3850bf7 100644 --- a/src/UserInterfaceManager.cpp +++ b/src/UserInterfaceManager.cpp @@ -2309,7 +2309,7 @@ void ToolBox::Render() static float recorded_bounds[3][2] = { {40.f, 65.f}, {1.f, 50.f}, {0.f, 50.f} }; static float refresh_rate = -1.f; static int values_index = 0; - float megabyte = static_cast( static_cast(SystemToolkit::memory_usage()) / 1048576.0 ); + float megabyte = static_cast( static_cast(FrameBuffer::memory_usage()) / 1000000.0 ); // init if (refresh_rate < 0.f) { @@ -2369,7 +2369,7 @@ void ToolBox::Render() ImGui::PlotLines("LinesRender", recorded_values[0], PLOT_ARRAY_SIZE, values_index, overlay, recorded_bounds[0][0], recorded_bounds[0][1], plot_size); snprintf(overlay, 128, "Update time %.1f ms (%.1f FPS)", recorded_sum[1] / float(PLOT_ARRAY_SIZE), (float(PLOT_ARRAY_SIZE) * 1000.f) / recorded_sum[1]); ImGui::PlotHistogram("LinesMixer", recorded_values[1], PLOT_ARRAY_SIZE, values_index, overlay, recorded_bounds[1][0], recorded_bounds[1][1], plot_size); - snprintf(overlay, 128, "Memory %.1f MB", recorded_values[2][(values_index+PLOT_ARRAY_SIZE-1) % PLOT_ARRAY_SIZE] ); + snprintf(overlay, 128, "Framebuffers %.1f MB", recorded_values[2][(values_index+PLOT_ARRAY_SIZE-1) % PLOT_ARRAY_SIZE] ); ImGui::PlotLines("LinesMemo", recorded_values[2], PLOT_ARRAY_SIZE, values_index, overlay, recorded_bounds[2][0], recorded_bounds[2][1], plot_size); ImGui::End();