Use vbo for draw call infos

This commit is contained in:
Atlante45 2016-01-18 18:55:31 -08:00
parent 7471646569
commit 6ee88c15ec
3 changed files with 44 additions and 14 deletions

View file

@ -52,8 +52,8 @@ public:
DrawCallInfo(Index idx) : index(idx) {}
Index index{0};
uint16_t unused{0}; // Reserved space for later
Index index { 0 };
uint16_t unused { 0 }; // Reserved space for later
};
// Make sure DrawCallInfo has no extra padding
@ -68,6 +68,7 @@ public:
BufferPointers buffers;
Function function;
DrawCallInfoBuffer drawCallInfos;
size_t numVertices;
size_t count() const { return drawCallInfos.size(); }

View file

@ -329,16 +329,19 @@ protected:
TransformCamera _camera;
TransformCameras _cameras;
GLuint _objectBuffer{ 0 };
GLuint _cameraBuffer{ 0 };
size_t _cameraUboSize{ 0 };
mutable std::map<std::string, GLvoid*> _drawCallInfoOffsets;
GLuint _objectBuffer { 0 };
GLuint _cameraBuffer { 0 };
GLuint _drawCallInfoBuffer { 0 };
size_t _cameraUboSize { 0 };
Transform _view;
Mat4 _projection;
Vec4i _viewport{ 0, 0, 1, 1 };
Vec2 _depthRange{ 0.0f, 1.0f };
bool _invalidView{false};
bool _invalidProj{false};
bool _invalidViewport{ false };
Vec4i _viewport { 0, 0, 1, 1 };
Vec2 _depthRange { 0.0f, 1.0f };
bool _invalidView { false };
bool _invalidProj { false };
bool _invalidViewport { false };
using Pair = std::pair<size_t, size_t>;
using List = std::list<Pair>;

View file

@ -61,6 +61,7 @@ void GLBackend::do_setDepthRangeTransform(Batch& batch, size_t paramOffset) {
void GLBackend::initTransform() {
glGenBuffers(1, &_transform._objectBuffer);
glGenBuffers(1, &_transform._cameraBuffer);
glGenBuffers(1, &_transform._drawCallInfoBuffer);
size_t cameraSize = sizeof(TransformCamera);
while (_transform._cameraUboSize < cameraSize) {
_transform._cameraUboSize += _uboAlignment;
@ -70,6 +71,7 @@ void GLBackend::initTransform() {
void GLBackend::killTransform() {
glDeleteBuffers(1, &_transform._objectBuffer);
glDeleteBuffers(1, &_transform._cameraBuffer);
glDeleteBuffers(1, &_transform._drawCallInfoBuffer);
}
void GLBackend::syncTransformStateCache() {
@ -140,6 +142,21 @@ void GLBackend::TransformStageState::transfer(const Batch& batch) const {
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
}
if (!batch._namedData.empty()) {
bufferData.clear();
for (auto& data : batch._namedData) {
auto currentSize = bufferData.size();
auto bytesToCopy = data.second.drawCallInfos.size() * sizeof(Batch::DrawCallInfo);
bufferData.resize(currentSize + bytesToCopy);
memcpy(bufferData.data() + currentSize, data.second.drawCallInfos.data(), bytesToCopy);
_drawCallInfoOffsets[data.first] = (GLvoid*)currentSize;
}
glBindBuffer(GL_ARRAY_BUFFER, _drawCallInfoBuffer);
glBufferData(GL_ARRAY_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
CHECK_GL_ERROR();
}
@ -169,12 +186,21 @@ void GLBackend::updateTransform(const Batch& batch) {
auto& drawCallInfoBuffer = batch.getDrawCallInfoBuffer();
if (batch._currentNamedCall.empty()) {
glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO);
auto& drawCallInfo = drawCallInfoBuffer[_currentDraw];
glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, (GLint)drawCallInfo.index, (GLint)drawCallInfo.unused);
glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled
glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused);
} else {
glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO);
glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_SHORT, 4, drawCallInfoBuffer.data());
if (false) {
auto& drawCallInfo = drawCallInfoBuffer[0];
glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled
glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused);
} else {
glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled
glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer);
glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0,
_transform._drawCallInfoOffsets[batch._currentNamedCall]);
glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 100000);
}
}
}