Bind model transform as single buffer

This commit is contained in:
Atlante45 2016-01-14 12:35:20 -08:00
parent bff2a2a8e5
commit 9e0af63441
4 changed files with 20 additions and 35 deletions

View file

@ -158,10 +158,9 @@ void GLBackend::renderPassTransfer(Batch& batch) {
{ // Sync all the buffers { // Sync all the buffers
PROFILE_RANGE("syncCPUTransform"); PROFILE_RANGE("syncCPUTransform");
_transform._cameras.resize(0); _transform._cameras.clear();
_transform._cameraOffsets.clear(); _transform._cameraOffsets.clear();
_transform._objects.resize(0); _transform._objects.clear();
_transform._objectOffsets.clear();
for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) {
switch (*command) { switch (*command) {
@ -196,10 +195,11 @@ void GLBackend::renderPassTransfer(Batch& batch) {
PROFILE_RANGE("syncGPUTransform"); PROFILE_RANGE("syncGPUTransform");
_transform.transfer(); _transform.transfer();
} }
} }
void GLBackend::renderPassDraw(Batch& batch) { void GLBackend::renderPassDraw(Batch& batch) {
_transform._objectsItr = _transform._objectOffsets.begin();
_transform._camerasItr = _transform._cameraOffsets.begin(); _transform._camerasItr = _transform._cameraOffsets.begin();
const size_t numCommands = batch.getCommands().size(); const size_t numCommands = batch.getCommands().size();
const Batch::Commands::value_type* command = batch.getCommands().data(); const Batch::Commands::value_type* command = batch.getCommands().data();

View file

@ -355,10 +355,9 @@ protected:
TransformObjects _objects; TransformObjects _objects;
TransformCameras _cameras; TransformCameras _cameras;
size_t _cameraUboSize{ 0 };
size_t _objectUboSize{ 0 };
GLuint _objectBuffer{ 0 }; GLuint _objectBuffer{ 0 };
GLuint _cameraBuffer{ 0 }; GLuint _cameraBuffer{ 0 };
size_t _cameraUboSize{ 0 };
Transform _model; Transform _model;
Transform _view; Transform _view;
Mat4 _projection; Mat4 _projection;
@ -372,8 +371,6 @@ protected:
using Pair = std::pair<size_t, size_t>; using Pair = std::pair<size_t, size_t>;
using List = std::list<Pair>; using List = std::list<Pair>;
List _cameraOffsets; List _cameraOffsets;
List _objectOffsets;
mutable List::const_iterator _objectsItr;
mutable List::const_iterator _camerasItr; mutable List::const_iterator _camerasItr;
void preUpdate(size_t commandIndex, const StereoState& stereo); void preUpdate(size_t commandIndex, const StereoState& stereo);

View file

@ -67,10 +67,6 @@ void GLBackend::initTransform() {
while (_transform._cameraUboSize < cameraSize) { while (_transform._cameraUboSize < cameraSize) {
_transform._cameraUboSize += _uboAlignment; _transform._cameraUboSize += _uboAlignment;
} }
size_t objectSize = sizeof(TransformObject);
while (_transform._objectUboSize < objectSize) {
_transform._objectUboSize += _uboAlignment;
}
} }
void GLBackend::killTransform() { void GLBackend::killTransform() {
@ -116,6 +112,8 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo
// of non-uniform scale. We need to fix that. In the mean time, glm::inverse() works. // of non-uniform scale. We need to fix that. In the mean time, glm::inverse() works.
//_model.getInverseMatrix(_object._modelInverse); //_model.getInverseMatrix(_object._modelInverse);
_object._modelInverse = glm::inverse(_object._model); _object._modelInverse = glm::inverse(_object._model);
_objects.push_back(_object);
} }
if (_invalidView || _invalidProj || _invalidViewport) { if (_invalidView || _invalidProj || _invalidViewport) {
@ -131,12 +129,6 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo
} }
} }
if (_invalidModel) {
size_t offset = _objectUboSize * _objects.size();
_objectOffsets.push_back(TransformStageState::Pair(commandIndex, offset));
_objects.push_back(_object);
}
// Flags are clean // Flags are clean
_invalidView = _invalidProj = _invalidModel = _invalidViewport = false; _invalidView = _invalidProj = _invalidModel = _invalidViewport = false;
} }
@ -145,42 +137,33 @@ void GLBackend::TransformStageState::transfer() const {
// FIXME not thread safe // FIXME not thread safe
static std::vector<uint8_t> bufferData; static std::vector<uint8_t> bufferData;
if (!_cameras.empty()) { if (!_cameras.empty()) {
glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer);
bufferData.resize(_cameraUboSize * _cameras.size()); bufferData.resize(_cameraUboSize * _cameras.size());
for (size_t i = 0; i < _cameras.size(); ++i) { for (size_t i = 0; i < _cameras.size(); ++i) {
memcpy(bufferData.data() + (_cameraUboSize * i), &_cameras[i], sizeof(TransformCamera)); memcpy(bufferData.data() + (_cameraUboSize * i), &_cameras[i], sizeof(TransformCamera));
} }
glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer);
glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW);
} }
if (!_objects.empty()) { if (!_objects.empty()) {
auto byteSize = _objects.size() * sizeof(TransformObject);
bufferData.resize(byteSize);
memcpy(bufferData.data(), _objects.data(), byteSize);
glBindBuffer(GL_UNIFORM_BUFFER, _objectBuffer); glBindBuffer(GL_UNIFORM_BUFFER, _objectBuffer);
bufferData.resize(_objectUboSize * _objects.size());
for (size_t i = 0; i < _objects.size(); ++i) {
memcpy(bufferData.data() + (_objectUboSize * i), &_objects[i], sizeof(TransformObject));
}
glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW);
} }
if (!_cameras.empty() || !_objects.empty()) { if (!_objects.empty() || !_cameras.empty()) {
glBindBuffer(GL_UNIFORM_BUFFER, 0); glBindBuffer(GL_UNIFORM_BUFFER, 0);
} }
CHECK_GL_ERROR(); CHECK_GL_ERROR();
} }
void GLBackend::TransformStageState::update(size_t commandIndex, const StereoState& stereo) const { void GLBackend::TransformStageState::update(size_t commandIndex, const StereoState& stereo) const {
static const size_t INVALID_OFFSET = (size_t)-1; static const size_t INVALID_OFFSET = (size_t)-1;
size_t offset = INVALID_OFFSET; size_t offset = INVALID_OFFSET;
while ((_objectsItr != _objectOffsets.end()) && (commandIndex >= (*_objectsItr).first)) {
offset = (*_objectsItr).second;
++_objectsItr;
}
if (offset != INVALID_OFFSET) {
glBindBufferRange(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT,
_objectBuffer, offset, sizeof(Backend::TransformObject));
}
offset = INVALID_OFFSET;
while ((_camerasItr != _cameraOffsets.end()) && (commandIndex >= (*_camerasItr).first)) { while ((_camerasItr != _cameraOffsets.end()) && (commandIndex >= (*_camerasItr).first)) {
offset = (*_camerasItr).second; offset = (*_camerasItr).second;
++_camerasItr; ++_camerasItr;
@ -194,6 +177,9 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta
_cameraBuffer, offset, sizeof(Backend::TransformCamera)); _cameraBuffer, offset, sizeof(Backend::TransformCamera));
} }
glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer);
(void)CHECK_GL_ERROR(); (void)CHECK_GL_ERROR();
} }

View file

@ -25,8 +25,10 @@ struct TransformCamera {
vec4 _viewport; vec4 _viewport;
}; };
const int MAX_OBJECTS = 512; // NEEDS to match GLBackend::TransformStageState::update's MAX_OBJECT
layout(std140) uniform transformObjectBuffer { layout(std140) uniform transformObjectBuffer {
TransformObject _object; TransformObject _object[MAX_OBJECTS];
}; };
TransformObject getTransformObject() { TransformObject getTransformObject() {
return _object; return _object;