From 73d29911044cfffdc7edad50aeb2a8d1175ecd11 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 25 Aug 2012 13:54:48 +0300 Subject: [PATCH] Track uniform buffer bindings --- flavors/gl/source/bufferstate.cpp | 7 +++++ flavors/gl/source/bufferstate.h | 10 +++++++ flavors/gl/source/glstate.cpp | 47 ++++++++++++++++++++++++++++++- flavors/gl/source/glstate.h | 7 +++++ flavors/gl/source/inspector.cpp | 8 ++++++ 5 files changed, 78 insertions(+), 1 deletion(-) diff --git a/flavors/gl/source/bufferstate.cpp b/flavors/gl/source/bufferstate.cpp index a8d5c4d..e48d221 100644 --- a/flavors/gl/source/bufferstate.cpp +++ b/flavors/gl/source/bufferstate.cpp @@ -168,3 +168,10 @@ string BufferState::describe() const else return strformat("%d bytes, %s", size, describe_enum(usage, "")); } + + +BufferBindingState::BufferBindingState(): + buffer(0), + offset(0), + size(0) +{ } diff --git a/flavors/gl/source/bufferstate.h b/flavors/gl/source/bufferstate.h index bf0e1ec..18013a7 100644 --- a/flavors/gl/source/bufferstate.h +++ b/flavors/gl/source/bufferstate.h @@ -3,6 +3,7 @@ #include #include +#include "autoconstptr.h" #include "opengl.h" struct ArrayState; @@ -46,4 +47,13 @@ struct BufferState std::string describe() const; }; +struct BufferBindingState +{ + AutoConstPtr buffer; + unsigned offset; + unsigned size; + + BufferBindingState(); +}; + #endif diff --git a/flavors/gl/source/glstate.cpp b/flavors/gl/source/glstate.cpp index 9fc2993..0163c2f 100644 --- a/flavors/gl/source/glstate.cpp +++ b/flavors/gl/source/glstate.cpp @@ -66,7 +66,9 @@ GlState::GlState(): active_tex(0), client_active_tex(0), array_buffer(0), - element_buffer(0) + element_buffer(0), + uniform_buffer(0), + uniform_bind_points(64) { vertex_array.kind = GL_VERTEX_ARRAY; normal_array.kind = GL_NORMAL_ARRAY; @@ -122,6 +124,8 @@ GlState::GlState(): decoder->glBindBuffer = glBindBuffer; decoder->glBindBufferARB = glBindBuffer; + decoder->glBindBufferBase = glBindBufferBase; + decoder->glBindBufferRange = glBindBufferRange; decoder->glBufferData = glBufferData; decoder->glBufferDataARB = glBufferData; decoder->glBufferSubData = glBufferSubData; @@ -160,6 +164,13 @@ const BufferState &GlState::get_buffer(unsigned id) const return i->second; } +const BufferBindingState &GlState::get_buffer_binding(GLenum target, unsigned index) const +{ + if(target==GL_UNIFORM_BUFFER) + return uniform_bind_points[index]; + throw runtime_error("This buffer target does not have indexed binding points"); +} + const ArrayState &GlState::get_array(GLenum array) const { if(array==GL_VERTEX_ARRAY) @@ -214,12 +225,27 @@ TextureState *GlState::get_current_texture(GLenum target) return texunits[active_tex].get_current_texture(target); } +BufferState *GlState::get_buffer_object(unsigned id) +{ + BufferMap::iterator i = buffers.find(id); + return (i==buffers.end() ? 0 : &i->second); +} + BufferState *GlState::get_current_buffer(GLenum target) { if(target==GL_ARRAY_BUFFER) return array_buffer; else if(target==GL_ELEMENT_ARRAY_BUFFER) return element_buffer; + else if(target==GL_UNIFORM_BUFFER) + return uniform_buffer; + return 0; +} + +BufferBindingState *GlState::get_buffer_binding(GLenum target, unsigned index) +{ + if(target==GL_UNIFORM_BUFFER) + return &uniform_bind_points[index]; return 0; } @@ -255,6 +281,8 @@ void GlState::set_current_buffer(GLenum target, unsigned id) array_buffer = buf; else if(target==GL_ELEMENT_ARRAY_BUFFER) element_buffer = buf; + else if(target==GL_UNIFORM_BUFFER) + uniform_buffer = buf; } ArrayState &GlState::get_attrib_array(unsigned index) @@ -412,6 +440,23 @@ void GlState::glVertexAttribPointer(void *user_data, unsigned index, int size, G void GlState::glBindBuffer(void *user_data, GLenum target, unsigned id) { reinterpret_cast(user_data)->set_current_buffer(target, id); } +void GlState::glBindBufferBase(void *user_data, GLenum target, unsigned index, unsigned id) +{ + if(BufferState *buffer = reinterpret_cast(user_data)->get_buffer_object(id)) + glBindBufferRange(user_data, target, index, id, 0, buffer->size); +} + +void GlState::glBindBufferRange(void *user_data, GLenum target, unsigned index, unsigned id, int offset, int size) +{ + GlState *self = reinterpret_cast(user_data); + if(BufferBindingState *binding = self->get_buffer_binding(target, index)) + { + binding->buffer = self->get_buffer_object(id); + binding->offset = offset; + binding->size = size; + } +} + void GlState::glBufferData(void *user_data, GLenum target, int size, const void *data, GLenum usage) { if(BufferState *buf = reinterpret_cast(user_data)->get_current_buffer(target)) diff --git a/flavors/gl/source/glstate.h b/flavors/gl/source/glstate.h index 7f15b01..e6a3d98 100644 --- a/flavors/gl/source/glstate.h +++ b/flavors/gl/source/glstate.h @@ -50,6 +50,8 @@ private: BufferMap buffers; BufferState *array_buffer; BufferState *element_buffer; + BufferState *uniform_buffer; + std::vector uniform_bind_points; ArrayState vertex_array; ArrayState normal_array; ArrayState color_array; @@ -70,13 +72,16 @@ public: const BufferMap &get_buffers() const { return buffers; } const BufferState &get_buffer(unsigned) const; const BufferState *get_current_buffer(GLenum) const; + const BufferBindingState &get_buffer_binding(GLenum, unsigned) const; const ArrayState &get_array(GLenum) const; const ArrayState &get_texture_coord_array(unsigned) const; const ArrayState &get_attrib_array(unsigned) const; private: bool &get_boolean_state(GLenum); TextureState *get_current_texture(GLenum); + BufferState *get_buffer_object(unsigned); BufferState *get_current_buffer(GLenum); + BufferBindingState *get_buffer_binding(GLenum, unsigned); void set_current_texture(GLenum, unsigned); void set_current_buffer(GLenum, unsigned); ArrayState &get_attrib_array(unsigned); @@ -110,6 +115,8 @@ private: static void glVertexAttribPointer(void *, unsigned, int, GLenum, unsigned char, int, const void *); static void glBindBuffer(void *, GLenum, unsigned); + static void glBindBufferBase(void *, GLenum, unsigned, unsigned); + static void glBindBufferRange(void *, GLenum, unsigned, unsigned, int, int); static void glBufferData(void *, GLenum, int, const void *, GLenum); static void glBufferSubData(void *, GLenum, int, int, const void *); static void glDeleteBuffers(void *, int, const unsigned *); diff --git a/flavors/gl/source/inspector.cpp b/flavors/gl/source/inspector.cpp index 936f7e8..150457e 100644 --- a/flavors/gl/source/inspector.cpp +++ b/flavors/gl/source/inspector.cpp @@ -72,6 +72,14 @@ void Inspector::cmd_state(const string &args) printf(" GL_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0)); buf = glstate.get_current_buffer(GL_ELEMENT_ARRAY_BUFFER); printf(" GL_ELEMENT_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0)); + buf = glstate.get_current_buffer(GL_UNIFORM_BUFFER); + printf(" GL_UNIFORM_BUFFER: %d\n", (buf ? buf->id : 0)); + for(unsigned i=0; i<64; ++i) + { + const BufferBindingState &binding = glstate.get_buffer_binding(GL_UNIFORM_BUFFER, i); + if(binding.buffer) + printf(" %d: %d (%d bytes at %d)\n", i, binding.buffer->id, binding.size, binding.offset); + } } else throw runtime_error("Invalid or missing argument"); -- 2.45.2