Files
fs2open.github.com/code/graphics/util/UniformAligner.cpp
T
asarium c6975fda3c Use uniform buffer blocks for passing uniform data to shaders
This uses UBOs for building a buffer object of uniform data before
using that data to draw objects. This should reduce the CPU overhead by
reducing the amount of glUniform calls required for executing a single
draw call. This is especially useful if rendering is limited by the CPU
which should help performance for people with slower CPUs.

This fixes #910.
2017-09-13 11:54:16 +02:00

88 lines
2.1 KiB
C++

//
//
#include "UniformAligner.h"
namespace {
size_t alignSize(size_t size, size_t align) {
if (align == 0) {
return size;
}
auto remainder = size % align;
if (remainder == 0) {
return size;
}
return size + align - remainder;
}
}
namespace graphics {
namespace util {
UniformAligner::UniformAligner(size_t dataSize, size_t headerSize) :
_numElements(0), _dataSize(dataSize), _headerSize(headerSize) {
// Make sure that the header space is already reserved
resize(0);
}
void UniformAligner::setAlignment(size_t align) {
// Clear the buffer since changing the alignment invalidates the stored data
clear();
_requiredAlignment = align;
}
void UniformAligner::resize(size_t num_elements) {
size_t final_size =
alignSize(_headerSize, _requiredAlignment) + alignSize(_dataSize, _requiredAlignment) * num_elements;
_buffer.resize(final_size);
_numElements = num_elements;
}
void* UniformAligner::addElement() {
_buffer.insert(_buffer.end(), alignSize(_dataSize, _requiredAlignment), 0);
++_numElements;
return getElement(_numElements - 1);
}
void* UniformAligner::getElement(size_t index) {
size_t offset = alignSize(_headerSize, _requiredAlignment) + alignSize(_dataSize, _requiredAlignment) * index;
Assertion(offset < _buffer.size(), "Invalid index specified!");
return reinterpret_cast<void*>(_buffer.data() + offset);
}
size_t UniformAligner::getOffset(size_t index) {
size_t offset = alignSize(_headerSize, _requiredAlignment) + alignSize(_dataSize, _requiredAlignment) * index;
Assertion(offset < _buffer.size(), "Invalid index specified!");
return offset;
}
void* UniformAligner::nextElement(void* currentEl) {
uint8_t* current = reinterpret_cast<uint8_t*>(currentEl);
current += alignSize(_dataSize, _requiredAlignment);
return reinterpret_cast<void*>(current);
}
size_t UniformAligner::getNumElements() {
return _numElements;
}
size_t UniformAligner::getSize() {
return _buffer.size();
}
void* UniformAligner::getData() {
return _buffer.data();
}
void UniformAligner::clear() {
resize(0);
}
size_t UniformAligner::getCurrentOffset() {
return getOffset(getNumElements() - 1);
}
}
}