From d72ef6d75a11f6cc05ab8ec039520719e1044741 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 25 Aug 2012 17:02:00 +0300 Subject: [PATCH] Query implementation limits on process startup --- flavors/gl/source/glstate.cpp | 58 +++++++++++++++++++-------------- flavors/gl/source/glstate.h | 21 +++++++----- flavors/gl/source/inspector.cpp | 45 ++++++++++++++++++++++--- flavors/gl/source/inspector.h | 8 +++++ source/functions.enum.t | 3 +- source/glwrap.c | 15 +++++++++ 6 files changed, 110 insertions(+), 40 deletions(-) diff --git a/flavors/gl/source/glstate.cpp b/flavors/gl/source/glstate.cpp index 7f67596..750d703 100644 --- a/flavors/gl/source/glstate.cpp +++ b/flavors/gl/source/glstate.cpp @@ -63,21 +63,22 @@ Vector4::Vector4(): GlState::GlState(): decoder(gldecoder_new(this, NULL)), + texcoord(1), active_tex(0), client_active_tex(0), + texunits(1), array_buffer(0), element_buffer(0), uniform_buffer(0), - uniform_bind_points(64) + texcoord_arrays(1) { vertex_array.kind = GL_VERTEX_ARRAY; normal_array.kind = GL_NORMAL_ARRAY; color_array.kind = GL_COLOR_ARRAY; - for(unsigned i=0; i<8; ++i) - { - texcoord_arrays[i].kind = GL_TEXTURE_COORD_ARRAY; - texcoord_arrays[i].index = i; - } + texcoord_arrays[0].kind = GL_TEXTURE_COORD_ARRAY; + texcoord_arrays[0].index = 0; + + decoder->glGetIntegerv = glGetIntegerv; decoder->glEnableClientState = glEnableClientState; decoder->glDisableClientState = glDisableClientState; @@ -169,6 +170,30 @@ int GlState::decode(const char *data, unsigned len) return gldecoder_decode(decoder, data, len); } +void GlState::glGetIntegerv(void *user_data, GLenum pname, int *param) +{ + GlState *self = reinterpret_cast(user_data); + if(pname==GL_MAX_TEXTURE_UNITS) + { + self->texcoord.resize(*param); + self->texunits.resize(*param); + self->texcoord_arrays.resize(*param); + for(unsigned i=0; itexcoord_arrays.size(); ++i) + { + self->texcoord_arrays[i].kind = GL_TEXTURE_COORD_ARRAY; + self->texcoord_arrays[i].index = i; + } + } + else if(pname==GL_MAX_VERTEX_ATTRIBS) + { + self->attrib_arrays.resize(*param); + for(unsigned i=0; iattrib_arrays.size(); ++i) + self->attrib_arrays[i].index = i; + } + else if(pname==GL_MAX_UNIFORM_BUFFER_BINDINGS) + self->uniform_bind_points.resize(*param); +} + // Boolean state bool &GlState::get_boolean_state(GLenum state) @@ -252,18 +277,6 @@ void GlState::glMultiTexCoord4f(void *user_data, unsigned index, float s, float // Vertex arrays -ArrayState &GlState::get_attrib_array(unsigned index) -{ - map::iterator i = attrib_arrays.find(index); - if(i!=attrib_arrays.end()) - return i->second; - - ArrayState &array = attrib_arrays[index]; - array.index = index; - - return array; -} - void GlState::glVertexPointer(void *user_data, int size, GLenum type, int stride, const void *data) { GlState *self = reinterpret_cast(user_data); @@ -306,7 +319,7 @@ void GlState::glDisableVertexAttribArray(void *user_data, unsigned index) void GlState::glVertexAttribPointer(void *user_data, unsigned index, int size, GLenum type, unsigned char norm, int stride, const void *data) { GlState *self = reinterpret_cast(user_data); - self->get_attrib_array(index).set(size, type, norm, stride, self->array_buffer, reinterpret_cast(data)); + self->attrib_arrays[index].set(size, type, norm, stride, self->array_buffer, reinterpret_cast(data)); } const ArrayState &GlState::get_array(GLenum array) const @@ -330,12 +343,7 @@ const ArrayState &GlState::get_texture_coord_array(unsigned index) const const ArrayState &GlState::get_attrib_array(unsigned index) const { - map::const_iterator i = attrib_arrays.find(index); - if(i!=attrib_arrays.end()) - return i->second; - - // XXX Return a dummy? - throw runtime_error("Unknown attribute array"); + return attrib_arrays[index]; } // Array draw commands diff --git a/flavors/gl/source/glstate.h b/flavors/gl/source/glstate.h index ab5ab05..1119195 100644 --- a/flavors/gl/source/glstate.h +++ b/flavors/gl/source/glstate.h @@ -29,9 +29,6 @@ struct Vector4 /** Tracks OpenGL state based on the command stream. This class is essentially a (partial) OpenGL implementation in itself. - -XXX Should determine the number of texture units the target implementation -actually supports. */ class GlState { @@ -44,12 +41,12 @@ public: private: GlDecoder *decoder; Vector4 color; - Vector4 texcoord[8]; + std::vector texcoord; Vector3 normal; unsigned active_tex; unsigned client_active_tex; TextureMap textures; - TexUnitState texunits[8]; + std::vector texunits; BufferMap buffers; BufferState *array_buffer; BufferState *element_buffer; @@ -58,8 +55,8 @@ private: ArrayState vertex_array; ArrayState normal_array; ArrayState color_array; - ArrayState texcoord_arrays[8]; - std::map attrib_arrays; + std::vector texcoord_arrays; + std::vector attrib_arrays; ShaderMap shaders; ProgramMap programs; @@ -69,6 +66,14 @@ public: int decode(const char *, unsigned); +private: + static void glGetIntegerv(void *, GLenum, int *); + +public: + unsigned get_max_texture_units() const { return texunits.size(); } + unsigned get_max_vertex_attribs() const { return attrib_arrays.size(); } + unsigned get_max_uniform_buffer_bindings() const { return uniform_bind_points.size(); } + private: bool &get_boolean_state(GLenum); static void glEnableClientState(void *, GLenum); @@ -89,8 +94,6 @@ public: const Vector3 &get_normal() const { return normal; } private: - ArrayState &get_attrib_array(unsigned); - static void glVertexPointer(void *, int, GLenum, int, const void *); static void glNormalPointer(void *, GLenum, int, const void *); static void glColorPointer(void *, int, GLenum, int, const void *); diff --git a/flavors/gl/source/inspector.cpp b/flavors/gl/source/inspector.cpp index f7d90f8..122c2e4 100644 --- a/flavors/gl/source/inspector.cpp +++ b/flavors/gl/source/inspector.cpp @@ -1,16 +1,21 @@ #include #include #include +#include "breakpoint.h" #include "enums.h" +#include "functions.h" #include "gldbg.h" #include "inspector.h" #include "strformat.h" using namespace std; -Inspector::Inspector(GlDbg &dbg) +Inspector::Inspector(GlDbg &d): + gldbg(d), + decoder(gldecoder_new(this, NULL)), + query_state(0) { - CommandInterpreter &cmd_interp = dbg.get_command_interpreter(); + CommandInterpreter &cmd_interp = gldbg.get_command_interpreter(); cmd_interp.register_command("state", this, &Inspector::cmd_state) .set_help("Inspects general GL state", @@ -46,13 +51,40 @@ Inspector::Inspector(GlDbg &dbg) " List program objects\n\n" "program ID\n" " Print information about a program object\n"); + + decoder->gldBreak = gldBreak; } void Inspector::decode(const char *data, unsigned len) { + if(query_state) + gldecoder_decode(decoder, data, len); state.decode(data, len); } +void Inspector::process_started() +{ + gldbg.set_breakpoint(FUNC_GLXMAKECURRENT, BREAK_RETURN, this); + query_state = 1; +} + +void Inspector::process_stopped(int reason) +{ + if((reason>>8)==3 && query_state==2) + { + GlPacket *pkt = packet_begin(FUNC_GLDQUERYLIMITS); + gldbg.send(pkt); + query_state = 0; + gldbg.resume_from_break(this); + } +} + +void Inspector::gldBreak(void *user_data, unsigned short func, unsigned char flag) +{ + if(func==FUNC_GLXMAKECURRENT && flag==BREAK_RETURN) + ++reinterpret_cast(user_data)->query_state; +} + void Inspector::print_indented(const string &str, unsigned indent) { string spaces(indent, ' '); @@ -77,7 +109,8 @@ void Inspector::cmd_state(const string &args) printf("Current vertex attributes:\n"); const Vector4 &color = glstate.get_color(); printf(" Color: [%05.3f, %05.3f, %05.3f, %05.3f]\n", color.r, color.g, color.b, color.a); - for(unsigned i=0; i<8; ++i) + unsigned count = glstate.get_max_texture_units(); + for(unsigned i=0; iid : 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) + count = glstate.get_max_uniform_buffer_bindings(); + for(unsigned i=0; i { private: + GlDbg &gldbg; GlState state; + GlDecoder *decoder; + int query_state; public: Inspector(GlDbg &); virtual void decode(const char *, unsigned); + virtual void process_started(); + virtual void process_stopped(int); + private: + static void gldBreak(void *, unsigned short, unsigned char); + void print_indented(const std::string &, unsigned); void cmd_state(const std::string &); diff --git a/source/functions.enum.t b/source/functions.enum.t index 20d6602..24d15c0 100644 --- a/source/functions.enum.t +++ b/source/functions.enum.t @@ -7,5 +7,6 @@ wl(' FUNC_%s,', func.name.upper()) : FUNC_GLDBREAK, : FUNC_GLDHOLD, : FUNC_GLDQUERYVIEWPORT, -: FUNC_GLDREADPIXELS +: FUNC_GLDREADPIXELS, +: FUNC_GLDQUERYLIMITS :}; diff --git a/source/glwrap.c b/source/glwrap.c index cd1c328..ee67957 100644 --- a/source/glwrap.c +++ b/source/glwrap.c @@ -179,6 +179,20 @@ static void receive_gldReadPixels(GlPacket *pkt) free(data); } +static void receive_gldQueryLimits(GlPacket *pkt UNUSED) +{ + int value; + + no_break = 1; + value = 0; + glGetIntegerv(GL_MAX_TEXTURE_UNITS, &value); + value = 0; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value); + value = 0; + glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &value); + no_break = 0; +} + static void receive(void) { GlPacket *pkt; @@ -194,6 +208,7 @@ static void receive(void) case FUNC_GLDHOLD: receive_gldHold(pkt); break; case FUNC_GLDQUERYVIEWPORT: receive_gldQueryViewport(pkt); break; case FUNC_GLDREADPIXELS: receive_gldReadPixels(pkt); break; + case FUNC_GLDQUERYLIMITS: receive_gldQueryLimits(pkt); break; default:; } } -- 2.45.2