]> git.tdb.fi Git - gldbg.git/commitdiff
Query implementation limits on process startup
authorMikko Rasa <tdb@tdb.fi>
Sat, 25 Aug 2012 14:02:00 +0000 (17:02 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 25 Aug 2012 17:32:03 +0000 (20:32 +0300)
flavors/gl/source/glstate.cpp
flavors/gl/source/glstate.h
flavors/gl/source/inspector.cpp
flavors/gl/source/inspector.h
source/functions.enum.t
source/glwrap.c

index 7f67596f099aa6581f2ef58c353d5cc40fb276ae..750d70315835a45395512512ce04ff2a2963cf3d 100644 (file)
@@ -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<GlState *>(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; i<self->texcoord_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; i<self->attrib_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<unsigned, ArrayState>::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<GlState *>(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<GlState *>(user_data);
-       self->get_attrib_array(index).set(size, type, norm, stride, self->array_buffer, reinterpret_cast<long>(data));
+       self->attrib_arrays[index].set(size, type, norm, stride, self->array_buffer, reinterpret_cast<long>(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<unsigned, ArrayState>::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
index ab5ab050a87e51f30e55fc8e577e6cb6b6c3ca72..11191955e93383839fc837cc7ac7597f06b64128 100644 (file)
@@ -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<Vector4> texcoord;
        Vector3 normal;
        unsigned active_tex;
        unsigned client_active_tex;
        TextureMap textures;
-       TexUnitState texunits[8];
+       std::vector<TexUnitState> 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<unsigned, ArrayState> attrib_arrays;
+       std::vector<ArrayState> texcoord_arrays;
+       std::vector<ArrayState> 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 *);
index f7d90f846802c72f97e63b1b6198d53127b70fd9..122c2e45298f340ddfe935a2f5e29375dcde480c 100644 (file)
@@ -1,16 +1,21 @@
 #include <stdexcept>
 #include <cstdio>
 #include <cstdlib>
+#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<Inspector *>(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; i<count; ++i)
                {
                        const Vector4 &texcoord = glstate.get_texcoord(i);
                        printf("  TexCoord%d: [%05.3f, %05.3f, %05.3f, %05.3f]\n", i, texcoord.s, texcoord.t, texcoord.p, texcoord.q);
@@ -88,7 +121,8 @@ void Inspector::cmd_state(const string &args)
        else if(args=="bind")
        {
                printf("Current bindings:\n");
-               for(unsigned i=0; i<8; ++i)
+               unsigned count = glstate.get_max_texture_units();
+               for(unsigned i=0; i<count; ++i)
                {
                        printf("  Texture unit %d:\n", i);
                        const TexUnitState &unit = glstate.get_texture_unit(i);
@@ -104,7 +138,8 @@ void Inspector::cmd_state(const string &args)
                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)
+               count = glstate.get_max_uniform_buffer_bindings();
+               for(unsigned i=0; i<count; ++i)
                {
                        const BufferBindingState &binding = glstate.get_buffer_binding(GL_UNIFORM_BUFFER, i);
                        if(binding.buffer)
index c4d3d06b56ce7773f35c208d26be0aecf8d90c43..3088a75d39590e0aa39e68db76b54a087baa4f5e 100644 (file)
@@ -7,13 +7,21 @@
 class Inspector: public RegisteredTool<Inspector>
 {
 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 &);
index 20d6602e472b65d882d58932c547542c0303adec..24d15c000200ce462eff717e7e04589149e10759 100644 (file)
@@ -7,5 +7,6 @@ wl('    FUNC_%s,', func.name.upper())
 :      FUNC_GLDBREAK,
 :      FUNC_GLDHOLD,
 :      FUNC_GLDQUERYVIEWPORT,
-:      FUNC_GLDREADPIXELS
+:      FUNC_GLDREADPIXELS,
+:      FUNC_GLDQUERYLIMITS
 :};
index cd1c328139e784f2a4bea80d90297e86401d4402..ee679577011931b7264fda5e011fecda59077d35 100644 (file)
@@ -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:;
                }
        }