As I've been writing the Mesa C++ wrappers I've come across some
dificulties posed by the way the interfaces are exported. As I
progressed I started to realize I was loosing too much time and effort
trying to fight the system, and the system in this case - Mesa - needs
not to be fought, but adapted to the new needs. Note that the changes I
propose aren't just to facilitate the C++ wrappers, they would give a
more consistent and efficient interface for C drivers, and are very well
in sync with other ongoing efforts on DRI (namely Keith Whitwell's
vtxfmt and Ian Romanick's texmem).


1. In the last IRC meeting (relevant part of the log attached) I already
focused on one of the aspects in Mesa's driver interfaces which wasn't
very convenient: the use of private structure pointers as a mechanism
for data inheritance. My proposal is to use structure compositing
instead of private pointers. This has the benefits of:
 - reduced memory allocation overhead and less referencing
 - more consistency between the base and inherited structures (no more
   things like driver private texture data having a seperate life from
   Mesa's texture.
 - in C++ we can describe inherited classes from mesa substrucutres as
   easily as subclassing.  This means that:
 - For every overloadable structure in Mesa, there is a function which
   takes a pointer to such structure and initializes it.
 - the driver is always the one who allocates the memory (as it's the
   only one who knows the full base+inhrited structure size), and has to
   call Mesa to initialize the data strutruture.  For many structures,
   Mesa already has one of the above things. The biggest exception (and
   biggest advantage) is the texture structure.
This is also the way that Ian has organized the texture structure in
texmem branch, so it will fit nicely there.


2. On user space, the current drivers are structured (with some
exceptions not relevent now) as follows:

  Client application
      |       |
      v       v
    glapi    GLX
      |       |
      v       v
    Mesa     DRI
      |       |
      v       v
      DRI_Driver
         |
         v
      Hardware
 
And the driver has to fill a Mesa callback function table. But, as Keith
recently said here, there is interest in having the drivers to deal
with the glapi dispatch table directly, in other words:

  Client application
      |       |
      v       v
    glapi    GLX
    : |       |
    : |       v
    : |      DRI
    : |       |
    : v       v
    : DRI_Driver
    : ^       |
    : |       |
    v v       v
    Mesa     Hardware

That is, instead of Mesa acting as the middle man, it should act more as
a library. This specificaly means that, instead of (phony names):

userapp.c:      glEnable(GL_TEXTURE);

mesa.c:         _mesa_Enable(enum) {
                  // Do its thing here
                  if(ctx->Driver.Enable)
                    ctx->Driver.Enable(ctx, enum);
                }

driver.c:       RadeonEnable(ctx, enum) {
                  // Do its thing here
                }

It would be:

userapp.c:      glEnable(GL_TEXTURE);

driver.c:       RadeonEnable(enum) {
                  // Do its thing here
                  _mesa_Enable(ctx, enum)
                  // ... or here
                }

mesa.c:         _mesa_Enable(enum) {
                  // Do its thing here
                }

Note that, according to the specific case, RadeonEnable may not even
xist, or don't call _mesa_Enable at all. And no time would be wasted on
doing unnecessary stuff (such as tables lookups, or maintaining
irrelevant state). And this may be controled on run-time via glapi. The
drawback here is that usually mesa verifies if the state changed before
notifying the driver, and this would be lost here - I really don't know
how much relevant this is.


3. Make the glapi get the current ctx pointer and pass it to the
functions. If I understood correcly, the drivers will have a per-context
dispatch table, which is on thread local storage (TLS). If so, this
means that the glapi already knows the current context pointer, so it
can pass it to the gl API entries, therefore using one less lookup to
the TLS.

This would also make the C++ simpler, and the ctx could be seen as an
abstract class, where the disptatch table were member functions. Of
course that the C++ call conventions don't allow this be just like that,
but from the C++ drivers point of view, it would be so. But this is not
the more important.


Finally I would like to discuss in which CVS repository the C++
framework and these ideas would go. My preference would be to do it on a
branch based on the embbeded branch on Mesa CVS. (This was also briefly
discusses in the last meeting).

A side note: if/when these things hit the DRI/Mesa trunks, if nobody
else wants to share it with, I take the resposability to update all
existing Mesa/DRI drivers. In any case, the changes can be a little time
consuming, but will be straightforward.

José Fonseca
<jfonseca> keithw: Is there any reason for "inheritence" in Mesa being achieved in 
most cases via private pointers instead of putting the base struct as the first field 
of the derived struct, and hence sharing the same base pointer?
<idr> jfonseca: I think that's so that the "base" can change in size without breaking 
things.
<idr> jfonseca: Also, then each "class" only has to allocate a chunk of memory for its 
data.
<keithw> jfonseca:  No - it's just the way it is
<jfonseca> keithw: The reason why I'm asking is that I'm considering "standardize" 
Mesa in the later approach for consistency and simplification. This will not only 
simplify the C++ bindings, but yield less allocations, as IDR noticed.
<keithw> jfonseca:  The base class thing does get to be a pain if you try & build deep 
inheritance that way.  The Xt widget library springs to mind.
<keithw> jfonseca:  But for mesa, I don't think it would be a problem.
<idr> keithw: I guess there are the same binary compat. issues that you have with 
sharing things between libGL.so and the client-driver or the X server and the X driver.
<jfonseca> keithw: You mean for the allocation.
<keithw> idr:  Yes, but binary compatibility is a recent concept.
<keithw> jose: Just generally Xt was a pain.
<jfonseca> keithw: Becuase for using is actually simpler, as less references  are 
needed.
<keithw> jfonseca:  It's probably true.  
<jfonseca> keithw: Anyway, I'm thinking in doing this while maintining source 
compatability, i.e., simply add the _mesa_init_* functions which don't exist already, 
and keep the private pointers.
<idr> keithw: k.
<keithw> jfonseca:  Sounds good.  I'm keen to see the results.
<keithw> jfonseca:  Brian may have more to say on the design choices...
<jfonseca> keithw: I'm going to use the CreateTexture driver function again for this 
(which was dead so far), so that the driver is called for the allocation of the 
texture, and call mesa back to initialize the base struct.
<keithw> jfonseca:  Where is that going to be called from?
<jfonseca> keithw: Sure. I'm going to send this to Mesa3d-dev. (Let me copy&paste now 
before the history gets lost...)
<jfonseca> keithw: The texture structure. When mesa wants to create a texture, it must 
ask the driver to allocate the memory (only the driver knows the full size of the 
inherited struct), and to initialize the texture private data. Currently these two 
things (mesa & driver init) are completly seperate, code- and time-wise.
<jfonseca> keithw: I think that by doing every thing this manner, things will be more 
consistent and efficient, bothe for C drivers and C++ bindings.
<keithw> jfonseca: OK, so this is from texobj.c somewhere -- _mesa_GenTextures, 
_mesa_BindTexture?
<jfonseca> keithw: That's right.
<keithw> jfonseca:  It's reasonable.  There have been all sorts of bugs because those 
two structs lead separate lives...
<idr> jfonseca: This sounds like what I do in the texmem code.
<jfonseca> idr: Really? I didn't knew you've been changing mesa internals there.
<idr> jfonseca: I don't.  But each driver inherits from driTextureObject (in texmem.h) 
in a similar why to what you're talking about.
<idr> jfonseca: With your changes we'd have mesaTextureObject -> driTextureObject -> 
r200TextureObject.
<jfonseca> idr: Ah... Ok. But between mesa<->driver things still use private pointers.
<jfonseca> idr: Ok. Nice.
<idr> jfonseca: Yes.  One of the fields of driTextureObject is a pointer to the 
gl_texture_object from Mesa.
<jfonseca> Ok. This changes take to another related subject, which is where to host 
the CVS repository of the C++ framework to start making these changes. I'm inclined 
towards using a branch based on embedded-0-1-branch in Mesa CVS, becausse it's 
smaller, has everything needed, and already has doxygen documentation which connects 
nicely to the C++ framework docs. Any comments?
<idr> jfonseca: I'd rather have it as a branch of the DRI tree.  Is it a good idea to 
have a branch of a branch? :)
<keithw> idr, jfonseca:  I'm interested in the idea of moving driver development to a 
smaller repository in the future - with the embedded branch as an idea of what that 
repository might look like
<keithw> .
<jfonseca> idr: It's *much* simpler to work with the embedded branch - everything is 
just one directory level away.
<idr> jfonseca: Fair enough.
<idr> jfonseca: I'm not leaning to hard either way. :)
<fxkuehl> jfonseca: At some point you're going to want to merge your Mesa changes to 
the Mesa trunk. I guess it'll be more work then.
<jfonseca> keithw: That seems good - the DRI repository isn't a full one anyway. One 
issue which has to be considered is the integration back in the X CVS.
<keithw> One thing to realize is that there are now two environments that I can build 
the drivers for -- XFree86/DRI and fbdev/miniglx.  These are mesa drivers first & 
foremost and the integration with a given windowsystem is actually a secondary choice.
<keithw> jfonseca:  I would put the drivers in extras/Mesa.  
<jfonseca> fxkuehl: Not with the C++ framework, since it will be basically add a new 
subdirectory, and a few changes in Mesa source. I.e., the changes will be fairly well 
contained. But don't know about general development.
<keithw> jfonseca:  That would make it clear to XFree people that patches should be 
submitted to Mesa/DRI/wherever-the-new-tree-lives.
<jfonseca> keithw: And what about changes in the DDX? There is no infrastructure for 
that in embedded-branch...
<keithw> fxkuehl:  The new tree would subsume *both* the dri and mesa trees
<keithw> jfonseca:  We'd have to keep the existing DRI tree for infrastructure work, 
or come up with a new mechanism.
<keithw> jfonseca:  Basically the proposal is:  "Move the 3d drivers into 
extras/Mesa".  Everything else follows from that.
<jfonseca> keithw: Isn't there a paradox in your two previous lines?
<keithw> jfonseca:  I preanswered your question
<keithw> jfonseca:  Do you see what I mean?   
<jfonseca> keithw: not really... :/ The paradox is you saying to fxkuehl "The new tree 
would subsume *both* the dri and mesa trees", and then "We'd have to keep the existing 
DRI tree for infrastructure work"...
<keithw> The new tree would subsume *both* the dri xc/lib/GL subtree and the mesa tree.
<keithw> jfonseca:  (trying to clarify)
<fxkuehl> keithw, jfonseca: are you talking about starting a new DRI CVS repository, 
or just a new subdir in the current DRI CVS tree?
<keithw> jfonseca:  The new tree would be imported to XFree cvs in the extras/Mesa 
directory.  So the drivers would get linked in along with the rest of mesa source.
<jfonseca> keithw: I think I'm understanding, but I don't see how it would simplify 
things if you keep the current DRI CVS, as you'd have to merge things back everytime 
you wanted to change the DDX or the infrastructure...
<keithw> fxkuehl:  A new tree somewhere.
<jfonseca> Ok. It'd be easy, since it would live under mesa.
<keithw> jfonseca:  OK.
<jfonseca> I think Brian should do the Mesa directory reorganization he mentioned 
before.
<fxkuehl> keithw: then the new tree would be the place for the client side driver 
development only. What about the kernel and X-server?
<keithw> fxkuehl:  The existing DRI tree would continue and be the place for server 
and probably kernel module development.
<keithw> fxkuehl:  Hmm.  Actually there are good reasons to consider splitting the 
kernel module out -- as it is no longer used exclusively by XFree86 (ie miniglx 
drivers use it too, now).
<idr> keithw: Shouldn't the kernel modules at least be in the same repository as the 
rest of the 3D driver?
<keithw> idr:  It makes sense, I think.  
<keithw> jfonseca:  The mesa directory reorg would be a good time to make the 
transition.

Reply via email to