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 | delete[] _writeVerticesArray; | 214 | delete[] _writeVerticesArray; |
| 215 | delete[] _readColorsArray; | 215 | delete[] _readColorsArray; |
| 216 | delete[] _writeColorsArray; | 216 | delete[] _writeColorsArray; |
| 217 | delete[] _writeVoxelDirtyArray; | ||
| 218 | delete[] _readVoxelDirtyArray; | ||
| 219 | } | 217 | } |
| 218 | delete[] _writeVoxelDirtyArray; | ||
| 219 | delete[] _readVoxelDirtyArray; | ||
| 220 | } | 220 | } |
| 221 | _initialized = false; // no longer initialized | 221 | _initialized = false; // no longer initialized |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | void VoxelSystem::initVoxelMemory() { | 224 | void VoxelSystem::initVoxelMemory() { |
| 225 | _initialMemoryUsageGPU = getFreeMemoryGPU(); | ||
| 226 | _memoryUsageRAM = 0; | ||
| 227 | _memoryUsageVBO = 0; // our VBO allocations as we know them | ||
| 225 | if (_useVoxelShader) { | 228 | if (_useVoxelShader) { |
| 226 | qDebug("Using Voxel Shader...\n"); | 229 | qDebug("Using Voxel Shader...\n"); |
| 227 | GLuint* indicesArray = new GLuint[_maxVoxels]; | 230 | GLuint* indicesArray = new GLuint[_maxVoxels]; |
| @@ -235,12 +238,13 @@ void VoxelSystem::initVoxelMemory() { · 7 unmodified lines | |||
| 235 | // bind the indices VBO to the actual indices array | 238 | // bind the indices VBO to the actual indices array |
| 236 | glGenBuffers(1, &_vboVoxelsIndicesID); | 239 | glGenBuffers(1, &_vboVoxelsIndicesID); |
| 237 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID); | 240 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID); |
| 238 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, _maxVoxels, indicesArray, GL_STATIC_DRAW); | 241 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * _maxVoxels, indicesArray, GL_STATIC_DRAW); |
| 239 | 242 | _memoryUsageVBO += sizeof(GLuint) * _maxVoxels; | |
| 240 | 243 | ||
| 241 | glGenBuffers(1, &_vboVoxelsID); | 244 | glGenBuffers(1, &_vboVoxelsID); |
| 242 | glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID); | 245 | glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID); |
| 243 | glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW); | 246 | glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW); |
| 247 | _memoryUsageVBO += _maxVoxels * sizeof(VoxelShaderVBOData); | ||
| 244 | 248 | ||
| 245 | // delete the indices and normals arrays that are no longer needed | 249 | // delete the indices and normals arrays that are no longer needed |
| 246 | delete[] indicesArray; | 250 | delete[] indicesArray; |
| @@ -248,12 +252,18 @@ void VoxelSystem::initVoxelMemory() { · 1 unmodified line | |||
| 248 | // we will track individual dirty sections with these arrays of bools | 252 | // we will track individual dirty sections with these arrays of bools |
| 249 | _writeVoxelDirtyArray = new bool[_maxVoxels]; | 253 | _writeVoxelDirtyArray = new bool[_maxVoxels]; |
| 250 | memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); | 254 | memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); |
| 255 | _memoryUsageRAM += (_maxVoxels * sizeof(bool)); | ||
| 256 | |||
| 251 | _readVoxelDirtyArray = new bool[_maxVoxels]; | 257 | _readVoxelDirtyArray = new bool[_maxVoxels]; |
| 252 | memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); | 258 | memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); |
| 259 | _memoryUsageRAM += (_maxVoxels * sizeof(bool)); | ||
| 253 | 260 | ||
| 254 | // prep the data structures for incoming voxel data | 261 | // prep the data structures for incoming voxel data |
| 255 | _writeVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; | 262 | _writeVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; |
| 263 | _memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels); | ||
| 264 | |||
| 256 | _readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; | 265 | _readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; |
| 266 | _memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels); | ||
| 257 | } else { | 267 | } else { |
| 258 | GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels]; | 268 | GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels]; |
| 259 | 269 | ||
| @@ -289,6 +299,7 @@ void VoxelSystem::initVoxelMemory() { · 29 unmodified lines | |||
| 289 | glBufferData(GL_ARRAY_BUFFER, | 299 | glBufferData(GL_ARRAY_BUFFER, |
| 290 | VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels, | 300 | VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels, |
| 291 | normalsArray, GL_STATIC_DRAW); | 301 | normalsArray, GL_STATIC_DRAW); |
| 302 | _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels; | ||
| 292 | 303 | ||
| 293 | // delete the indices and normals arrays that are no longer needed | 304 | // delete the indices and normals arrays that are no longer needed |
| 294 | delete[] normalsArray; | 305 | delete[] normalsArray; |
| @@ -310,6 +321,7 @@ void VoxelSystem::initVoxelMemory() { · 15 unmodified lines | |||
| 310 | glBufferData(GL_ARRAY_BUFFER, | 321 | glBufferData(GL_ARRAY_BUFFER, |
| 311 | VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, | 322 | VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, |
| 312 | normalsArray, GL_STATIC_DRAW); | 323 | normalsArray, GL_STATIC_DRAW); |
| 324 | _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels; | ||
| 313 | 325 | ||
| 314 | // delete the indices and normals arrays that are no longer needed | 326 | // delete the indices and normals arrays that are no longer needed |
| 315 | delete[] normalsArray; | 327 | delete[] normalsArray; |
| @@ -319,11 +331,13 @@ void VoxelSystem::initVoxelMemory() { · 3 unmodified lines | |||
| 319 | glGenBuffers(1, &_vboVerticesID); | 331 | glGenBuffers(1, &_vboVerticesID); |
| 320 | glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); | 332 | glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); |
| 321 | glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); | 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 | // VBO for colorsArray | 336 | // VBO for colorsArray |
| 324 | glGenBuffers(1, &_vboColorsID); | 337 | glGenBuffers(1, &_vboColorsID); |
| 325 | glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); | 338 | glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); |
| 326 | glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); | 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 | // VBO for the indicesArray | 342 | // VBO for the indicesArray |
| 329 | glGenBuffers(1, &_vboIndicesID); | 343 | glGenBuffers(1, &_vboIndicesID); |
| @@ -331,6 +345,7 @@ void VoxelSystem::initVoxelMemory() { · 1 unmodified line | |||
| 331 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, | 345 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, |
| 332 | INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels, | 346 | INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels, |
| 333 | indicesArray, GL_STATIC_DRAW); | 347 | indicesArray, GL_STATIC_DRAW); |
| 348 | _memoryUsageVBO += INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels; | ||
| 334 | 349 | ||
| 335 | // delete the indices and normals arrays that are no longer needed | 350 | // delete the indices and normals arrays that are no longer needed |
| 336 | delete[] indicesArray; | 351 | delete[] indicesArray; |
| @@ -339,15 +354,22 @@ void VoxelSystem::initVoxelMemory() { · 2 unmodified lines | |||
| 339 | // we will track individual dirty sections with these arrays of bools | 354 | // we will track individual dirty sections with these arrays of bools |
| 340 | _writeVoxelDirtyArray = new bool[_maxVoxels]; | 355 | _writeVoxelDirtyArray = new bool[_maxVoxels]; |
| 341 | memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); | 356 | memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); |
| 357 | _memoryUsageRAM += (sizeof(bool) * _maxVoxels); | ||
| 358 | |||
| 342 | _readVoxelDirtyArray = new bool[_maxVoxels]; | 359 | _readVoxelDirtyArray = new bool[_maxVoxels]; |
| 343 | memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); | 360 | memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); |
| 361 | _memoryUsageRAM += (sizeof(bool) * _maxVoxels); | ||
| 344 | 362 | ||
| 345 | // prep the data structures for incoming voxel data | 363 | // prep the data structures for incoming voxel data |
| 346 | _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; | 364 | _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; |
| 365 | _memoryUsageRAM += (sizeof(GLfloat) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); | ||
| 347 | _readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; | 366 | _readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; |
| 367 | _memoryUsageRAM += (sizeof(GLfloat) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); | ||
| 348 | 368 | ||
| 349 | _writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; | 369 | _writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; |
| 370 | _memoryUsageRAM += (sizeof(GLubyte) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); | ||
| 350 | _readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; | 371 | _readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; |
| 372 | _memoryUsageRAM += (sizeof(GLubyte) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); | ||
| 351 | 373 | ||
| 352 | 374 | ||
| 353 | // create our simple fragment shader if we're the first system to init | 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 | |||