Showing the changes to interface/src/VoxelSystem.cpp (1 of 3 files). Show all
Unified · Split
| @@ -214,14 +214,17 @@ void VoxelSystem::cleanupVoxelMemory() { · 213 unmodified lines | ||
| 214 | 214 | delete[] _writeVerticesArray; |
| 215 | 215 | delete[] _readColorsArray; |
| 216 | 216 | delete[] _writeColorsArray; |
| 217 | − delete[] _writeVoxelDirtyArray; | |
| 218 | − delete[] _readVoxelDirtyArray; | |
| 219 | 217 | } |
| 218 | + delete[] _writeVoxelDirtyArray; | |
| 219 | + delete[] _readVoxelDirtyArray; | |
| 220 | 220 | } |
| 221 | 221 | _initialized = false; // no longer initialized |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | 224 | void VoxelSystem::initVoxelMemory() { |
| 225 | + _initialMemoryUsageGPU = getFreeMemoryGPU(); | |
| 226 | + _memoryUsageRAM = 0; | |
| 227 | + _memoryUsageVBO = 0; // our VBO allocations as we know them | |
| 225 | 228 | if (_useVoxelShader) { |
| 226 | 229 | qDebug("Using Voxel Shader...\n"); |
| 227 | 230 | GLuint* indicesArray = new GLuint[_maxVoxels]; |
| @@ -235,12 +238,13 @@ void VoxelSystem::initVoxelMemory() { · 7 unmodified lines | ||
| 235 | 238 | // bind the indices VBO to the actual indices array |
| 236 | 239 | glGenBuffers(1, &_vboVoxelsIndicesID); |
| 237 | 240 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID); |
| 238 | − glBufferData(GL_ELEMENT_ARRAY_BUFFER, _maxVoxels, indicesArray, GL_STATIC_DRAW); | |
| 239 | − | |
| 241 | + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * _maxVoxels, indicesArray, GL_STATIC_DRAW); | |
| 242 | + _memoryUsageVBO += sizeof(GLuint) * _maxVoxels; | |
| 240 | 243 | |
| 241 | 244 | glGenBuffers(1, &_vboVoxelsID); |
| 242 | 245 | glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID); |
| 243 | 246 | glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW); |
| 247 | + _memoryUsageVBO += _maxVoxels * sizeof(VoxelShaderVBOData); | |
| 244 | 248 | |
| 245 | 249 | // delete the indices and normals arrays that are no longer needed |
| 246 | 250 | delete[] indicesArray; |
| @@ -248,12 +252,18 @@ void VoxelSystem::initVoxelMemory() { · 1 unmodified line | ||
| 248 | 252 | // we will track individual dirty sections with these arrays of bools |
| 249 | 253 | _writeVoxelDirtyArray = new bool[_maxVoxels]; |
| 250 | 254 | memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); |
| 255 | + _memoryUsageRAM += (_maxVoxels * sizeof(bool)); | |
| 256 | + | |
| 251 | 257 | _readVoxelDirtyArray = new bool[_maxVoxels]; |
| 252 | 258 | memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); |
| 259 | + _memoryUsageRAM += (_maxVoxels * sizeof(bool)); | |
| 253 | 260 | |
| 254 | 261 | // prep the data structures for incoming voxel data |
| 255 | 262 | _writeVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; |
| 263 | + _memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels); | |
| 264 | + | |
| 256 | 265 | _readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; |
| 266 | + _memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels); | |
| 257 | 267 | } else { |
| 258 | 268 | GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels]; |
| 259 | 269 | |
| @@ -289,6 +299,7 @@ void VoxelSystem::initVoxelMemory() { · 29 unmodified lines | ||
| 289 | 299 | glBufferData(GL_ARRAY_BUFFER, |
| 290 | 300 | VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels, |
| 291 | 301 | normalsArray, GL_STATIC_DRAW); |
| 302 | + _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels; | |
| 292 | 303 | |
| 293 | 304 | // delete the indices and normals arrays that are no longer needed |
| 294 | 305 | delete[] normalsArray; |
| @@ -310,6 +321,7 @@ void VoxelSystem::initVoxelMemory() { · 15 unmodified lines | ||
| 310 | 321 | glBufferData(GL_ARRAY_BUFFER, |
| 311 | 322 | VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, |
| 312 | 323 | normalsArray, GL_STATIC_DRAW); |
| 324 | + _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels; | |
| 313 | 325 | |
| 314 | 326 | // delete the indices and normals arrays that are no longer needed |
| 315 | 327 | delete[] normalsArray; |
| @@ -319,11 +331,13 @@ void VoxelSystem::initVoxelMemory() { · 3 unmodified lines | ||
| 319 | 331 | glGenBuffers(1, &_vboVerticesID); |
| 320 | 332 | glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); |
| 321 | 333 | glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); |
| 334 | + _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels; | |
| 322 | 335 | |
| 323 | 336 | // VBO for colorsArray |
| 324 | 337 | glGenBuffers(1, &_vboColorsID); |
| 325 | 338 | glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); |
| 326 | 339 | glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); |
| 340 | + _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels; | |
| 327 | 341 | |
| 328 | 342 | // VBO for the indicesArray |
| 329 | 343 | glGenBuffers(1, &_vboIndicesID); |
| @@ -331,6 +345,7 @@ void VoxelSystem::initVoxelMemory() { · 1 unmodified line | ||
| 331 | 345 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, |
| 332 | 346 | INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels, |
| 333 | 347 | indicesArray, GL_STATIC_DRAW); |
| 348 | + _memoryUsageVBO += INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels; | |
| 334 | 349 | |
| 335 | 350 | // delete the indices and normals arrays that are no longer needed |
| 336 | 351 | delete[] indicesArray; |
| @@ -339,15 +354,22 @@ void VoxelSystem::initVoxelMemory() { · 2 unmodified lines | ||
| 339 | 354 | // we will track individual dirty sections with these arrays of bools |
| 340 | 355 | _writeVoxelDirtyArray = new bool[_maxVoxels]; |
| 341 | 356 | memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); |
| 357 | + _memoryUsageRAM += (sizeof(bool) * _maxVoxels); | |
| 358 | + | |
| 342 | 359 | _readVoxelDirtyArray = new bool[_maxVoxels]; |
| 343 | 360 | memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); |
| 361 | + _memoryUsageRAM += (sizeof(bool) * _maxVoxels); | |
| 344 | 362 | |
| 345 | 363 | // prep the data structures for incoming voxel data |
| 346 | 364 | _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; |
| 365 | + _memoryUsageRAM += (sizeof(GLfloat) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); | |
| 347 | 366 | _readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; |
| 367 | + _memoryUsageRAM += (sizeof(GLfloat) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); | |
| 348 | 368 | |
| 349 | 369 | _writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; |
| 370 | + _memoryUsageRAM += (sizeof(GLubyte) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); | |
| 350 | 371 | _readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; |
| 372 | + _memoryUsageRAM += (sizeof(GLubyte) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); | |
| 351 | 373 | |
| 352 | 374 | |
| 353 | 375 | // create our simple fragment shader if we're the first system to init |
| @@ -1897,3 +1919,58 @@ void VoxelSystem::nodeKilled(Node* node) { · 1543 unmodified lines | ||
| 1897 | 1919 | } |
| 1898 | 1920 | |
| 1899 | 1921 | |
| 1922 | +unsigned long VoxelSystem::getFreeMemoryGPU() { | |
| 1923 | + // We can't ask all GPUs how much memory they have in use, but we can ask them about how much is free. | |
| 1924 | + // So, we can record the free memory before we create our VBOs and the free memory after, and get a basic | |
| 1925 | + // idea how how much we're using. | |
| 1926 | + | |
| 1927 | + _hasMemoryUsageGPU = false; // assume the worst | |
| 1928 | + unsigned long freeMemory = 0; | |
| 1929 | + const int NUM_RESULTS = 4; // see notes, these APIs return up to 4 results | |
| 1930 | + GLint results[NUM_RESULTS] = { 0, 0, 0, 0}; | |
| 1931 | + | |
| 1932 | + // ATI | |
| 1933 | + // http://www.opengl.org/registry/specs/ATI/meminfo.txt | |
| 1934 | + // | |
| 1935 | + // TEXTURE_FREE_MEMORY_ATI 0x87FC | |
| 1936 | + // RENDERBUFFER_FREE_MEMORY_ATI 0x87FD | |
| 1937 | + const GLenum VBO_FREE_MEMORY_ATI = 0x87FB; | |
| 1938 | + glGetIntegerv(VBO_FREE_MEMORY_ATI, &results[0]); | |
| 1939 | + GLenum errorATI = glGetError(); | |
| 1940 | + | |
| 1941 | + if (errorATI == GL_NO_ERROR) { | |
| 1942 | + _hasMemoryUsageGPU = true; | |
| 1943 | + freeMemory = results[0]; | |
| 1944 | + } else { | |
| 1945 | + | |
| 1946 | + // NVIDIA | |
| 1947 | + // http://developer.download.nvidia.com/opengl/specs/GL_NVX_gpu_memory_info.txt | |
| 1948 | + // | |
| 1949 | + //const GLenum GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX = 0x9047; | |
| 1950 | + //const GLenum GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A; | |
| 1951 | + //const GLenum GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B; | |
| 1952 | + //const GLenum GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048; | |
| 1953 | + | |
| 1954 | + const GLenum GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049; | |
| 1955 | + results[0] = 0; | |
| 1956 | + glGetIntegerv(GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &results[0]); | |
| 1957 | + freeMemory += results[0]; | |
| 1958 | + GLenum errorNVIDIA = glGetError(); | |
| 1959 | + | |
| 1960 | + if (errorNVIDIA == GL_NO_ERROR) { | |
| 1961 | + _hasMemoryUsageGPU = true; | |
| 1962 | + freeMemory = results[0]; | |
| 1963 | + } | |
| 1964 | + } | |
| 1965 | + | |
| 1966 | + const unsigned long BYTES_PER_KBYTE = 1024; | |
| 1967 | + return freeMemory * BYTES_PER_KBYTE; // API results in KB, we want it in bytes | |
| 1968 | +} | |
| 1969 | + | |
| 1970 | +unsigned long VoxelSystem::getVoxelMemoryUsageGPU() { | |
| 1971 | + unsigned long currentFreeMemory = getFreeMemoryGPU(); | |
| 1972 | + return (_initialMemoryUsageGPU - currentFreeMemory); | |
| 1973 | +} | |
| 1974 | + | |
| 1975 | + | |
| 1976 | + | |