Files
fs2open.github.com/code/graphics/util/UniformBufferManager.cpp
T
asarium 39ab45dc7c Add macro for marking unreachable code
This can be used for mark parts of the code which should be unreachable
in normal execution. In debug mode, if such a statement is reached an
Error dialog is shown which aborts the execution. In release mode the
macro is replaced with a compiler specific expression that lets the
compiler know that this part is unreachable which allows it to optimize
the code better.
2018-06-09 17:38:17 +02:00

88 lines
2.2 KiB
C++

#include "UniformBufferManager.h"
#include "uniform_structs.h"
namespace {
size_t getElementSize(uniform_block_type type) {
switch (type) {
case uniform_block_type::Lights:
return sizeof(graphics::deferred_light_data);
case uniform_block_type::ModelData:
return sizeof(graphics::model_uniform_data);
case uniform_block_type::NanoVGData:
return sizeof(graphics::nanovg_draw_data);
case uniform_block_type::DecalInfo:
return sizeof(graphics::decal_info);
case uniform_block_type::NUM_BLOCK_TYPES:
default:
UNREACHABLE("Invalid block type encountered!");
return 0;
}
}
size_t getHeaderSize(uniform_block_type type) {
switch (type) {
case uniform_block_type::Lights:
return sizeof(graphics::deferred_global_data);
case uniform_block_type::DecalInfo:
return sizeof(graphics::decal_globals);
case uniform_block_type::ModelData:
case uniform_block_type::NanoVGData:
return 0;
case uniform_block_type::NUM_BLOCK_TYPES:
default:
UNREACHABLE("Invalid block type encountered!");
return 0;
}
}
}
namespace graphics {
namespace util {
UniformBufferManager::UniformBufferManager(uniform_block_type uniform_type) : _type(uniform_type) {
}
UniformBuffer* UniformBufferManager::getBuffer() {
if (!_retiredBuffers.empty()) {
// Reuse one of the free buffers
auto buffer = _retiredBuffers.back();
// Sanity check
Assertion(!buffer->isInUse(), "Retired buffer is in use!");
_retiredBuffers.pop_back();
_usedBuffers.push_back(buffer);
return buffer;
}
// No free buffers available, create a new one
std::unique_ptr<UniformBuffer> buffer(new UniformBuffer(getElementSize(_type), getHeaderSize(_type)));
auto ptr = buffer.get();
_buffers.push_back(std::move(buffer));
_usedBuffers.push_back(ptr);
return ptr;
}
void UniformBufferManager::retireBuffers() {
GR_DEBUG_SCOPE("Retiring buffers of buffer manager");
for (auto& buffer : _usedBuffers) {
if (!buffer->isInUse()) {
// This buffer will be retired soon so add it to the list before removing it from the used list
_retiredBuffers.push_back(buffer);
}
}
// Remove the buffers from the list
_usedBuffers.erase(std::remove_if(_usedBuffers.begin(), _usedBuffers.end(), [](UniformBuffer* buffer) {
return !buffer->isInUse();
}), _usedBuffers.end());
}
}
}