mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 09:18:45 +02:00
Merge pull request #278 from ZappoMan/render_voxels_optimization
Implement Partial VBO strategy in copyWrittenDataToReadArrays()
This commit is contained in:
commit
97f91403a3
2 changed files with 82 additions and 11 deletions
|
@ -205,17 +205,86 @@ void VoxelSystem::cleanupRemovedVoxels() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() {
|
||||||
|
// lock on the buffer write lock so we can't modify the data when the GPU is reading it
|
||||||
|
pthread_mutex_lock(&_bufferWriteLock);
|
||||||
|
int bytesOfVertices = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLfloat);
|
||||||
|
int bytesOfColors = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLubyte);
|
||||||
|
memcpy(_readVerticesArray, _writeVerticesArray, bytesOfVertices);
|
||||||
|
memcpy(_readColorsArray, _writeColorsArray, bytesOfColors );
|
||||||
|
_voxelsInReadArrays = _voxelsInWriteArrays;
|
||||||
|
pthread_mutex_unlock(&_bufferWriteLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() {
|
||||||
|
// lock on the buffer write lock so we can't modify the data when the GPU is reading it
|
||||||
|
pthread_mutex_lock(&_bufferWriteLock);
|
||||||
|
|
||||||
|
glBufferIndex segmentStart = 0;
|
||||||
|
glBufferIndex segmentEnd = 0;
|
||||||
|
bool inSegment = false;
|
||||||
|
for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) {
|
||||||
|
bool thisVoxelDirty = _voxelDirtyArray[i];
|
||||||
|
if (!inSegment) {
|
||||||
|
if (thisVoxelDirty) {
|
||||||
|
segmentStart = i;
|
||||||
|
inSegment = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!thisVoxelDirty) {
|
||||||
|
// If we got here because because this voxel is NOT dirty, so the last dirty voxel was the one before
|
||||||
|
// this one and so that's where the "segment" ends
|
||||||
|
segmentEnd = i - 1;
|
||||||
|
inSegment = false;
|
||||||
|
int segmentLength = (segmentEnd - segmentStart) + 1;
|
||||||
|
|
||||||
|
GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
memcpy(readVerticesAt, writeVerticesAt, segmentSizeBytes);
|
||||||
|
|
||||||
|
segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
|
segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
|
GLubyte* readColorsAt = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
memcpy(readColorsAt, writeColorsAt, segmentSizeBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we got to the end of the array, and we're in an active dirty segment...
|
||||||
|
if (inSegment) {
|
||||||
|
segmentEnd = _voxelsInWriteArrays - 1;
|
||||||
|
int segmentLength = (segmentEnd - segmentStart) + 1;
|
||||||
|
|
||||||
|
GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
memcpy(readVerticesAt, writeVerticesAt, segmentSizeBytes);
|
||||||
|
|
||||||
|
segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
|
segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
|
GLubyte* readColorsAt = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
|
memcpy(readColorsAt, writeColorsAt, segmentSizeBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update our length
|
||||||
|
_voxelsInReadArrays = _voxelsInWriteArrays;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&_bufferWriteLock);
|
||||||
|
}
|
||||||
|
|
||||||
void VoxelSystem::copyWrittenDataToReadArrays() {
|
void VoxelSystem::copyWrittenDataToReadArrays() {
|
||||||
PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()"); // would like to include _voxelsInArrays, _voxelsUpdated
|
PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()");
|
||||||
if (_voxelsDirty && _voxelsUpdated) {
|
if (_voxelsDirty && _voxelsUpdated) {
|
||||||
// lock on the buffer write lock so we can't modify the data when the GPU is reading it
|
if (_renderFullVBO) {
|
||||||
pthread_mutex_lock(&_bufferWriteLock);
|
copyWrittenDataToReadArraysFullVBOs();
|
||||||
int bytesOfVertices = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLfloat);
|
} else {
|
||||||
int bytesOfColors = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLubyte);
|
copyWrittenDataToReadArraysPartialVBOs();
|
||||||
memcpy(_readVerticesArray, _writeVerticesArray, bytesOfVertices);
|
}
|
||||||
memcpy(_readColorsArray, _writeColorsArray, bytesOfColors );
|
|
||||||
_voxelsInReadArrays = _voxelsInWriteArrays;
|
|
||||||
pthread_mutex_unlock(&_bufferWriteLock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,11 +562,10 @@ void VoxelSystem::updateVBOs() {
|
||||||
};
|
};
|
||||||
PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays
|
PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays
|
||||||
if (_voxelsDirty) {
|
if (_voxelsDirty) {
|
||||||
// updatePartialVBOs() is not yet working. For now, ALWAYS call updateFullVBOs()
|
|
||||||
if (_renderFullVBO) {
|
if (_renderFullVBO) {
|
||||||
updateFullVBOs();
|
updateFullVBOs();
|
||||||
} else {
|
} else {
|
||||||
updatePartialVBOs(); // too many small segments?
|
updatePartialVBOs();
|
||||||
}
|
}
|
||||||
_voxelsDirty = false;
|
_voxelsDirty = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,9 @@ private:
|
||||||
int updateNodeInArraysAsFullVBO(VoxelNode* node);
|
int updateNodeInArraysAsFullVBO(VoxelNode* node);
|
||||||
int updateNodeInArraysAsPartialVBO(VoxelNode* node);
|
int updateNodeInArraysAsPartialVBO(VoxelNode* node);
|
||||||
|
|
||||||
|
void copyWrittenDataToReadArraysFullVBOs();
|
||||||
|
void copyWrittenDataToReadArraysPartialVBOs();
|
||||||
|
|
||||||
// these are kinda hacks, used by getDistanceFromViewRangeOperation() probably shouldn't be here
|
// these are kinda hacks, used by getDistanceFromViewRangeOperation() probably shouldn't be here
|
||||||
static float _maxDistance;
|
static float _maxDistance;
|
||||||
static float _minDistance;
|
static float _minDistance;
|
||||||
|
|
Loading…
Reference in a new issue