[Mesa-dev] [PATCH v2 5/5] i965/gen6: Initial implementation of MSAA.

Ian Romanick idr at freedesktop.org
Thu May 17 16:00:43 PDT 2012


On 05/17/2012 03:43 PM, Paul Berry wrote:
> On 17 May 2012 11:21, Ian Romanick <idr at freedesktop.org
> <mailto:idr at freedesktop.org>> wrote:
>
>     On 05/14/2012 06:24 PM, Paul Berry wrote:
>
>         On 14 May 2012 16:50, Ian Romanick <idr at freedesktop.org
>         <mailto:idr at freedesktop.org>
>         <mailto:idr at freedesktop.org <mailto:idr at freedesktop.org>>> wrote:
>
>             On 05/14/2012 02:13 PM, Paul Berry wrote:
>
>                 Just to update the list: I had an in-person meeting with
>         Eric,
>                 Ian, and
>                 Ken today to discuss the design of the patch series and
>         decide
>                 what to
>                 do about it.  We agreed to go ahead and push the patches to
>                 master as
>                 is, and to make further improvements as time goes on.
>
>                 Specific improvements that were discussed:
>
>                 - I seem to be the only person who thinks it makes sense
>         for the
>                 brw_blorp_params class to contain an exec() function.
>           In the
>                 interest
>                 of avoiding a rebasing nightmare, I will go ahead with the
>                 patches as
>                 they are, and submitt a follow up patch which replaces
>                 brw_blorp_params::exec() with a global function
>         brw_blorp_exec(const
>                 brw_blorp_params *).
>
>
>             Part of the issue was that "exec" isn't a terrific name, and
>             exec'ing a set of parameters doesn't have implicit meaning.  My
>             preference was for a function, similar to what you mention,
>         called
>             brw_blorp_do_blit or similar.
>
>
>         I'm not going to try to change your mind, but in the spirit of
>         clarifying the method that was behind my madness:
>
>         I did not have the clarity of mind during our discussion today
>         to point
>         out that in creating the brw_blorp_params class, I was in fact
>         trying to
>         follow a standard design pattern, the Gang of Four "command" pattern
>         (http://en.wikipedia.org/wiki/__Command_pattern
>         <http://en.wikipedia.org/wiki/Command_pattern>).  The idea of that
>
>
>     There are some other places, mostly in the compiler, where various
>     patterns are employed.  In those cases, I've explicitly put in a
>     comment like, "This is pattern XYZ.  Refer to http://foo/ for the
>     back story." The comment block in
>     src/glsl/ir_hierarchical___visitor.h is an example.
>
>
>         pattern is to encapsulate all of the information necessary to
>         perform an
>         action into a class; this allows the action to be treated as a first
>         class object.  The usual reasons why it might be useful for the
>         action
>         to be a first class object are so that it can be stored in an undo
>         history, so that its execution can be deferred, restarted, or
>         repeated,
>         or so that some other part of the program can take the
>         opportunity to
>         tweak the parameters before the action is performed.  In this
>         particular
>         case the benefit is that the various phases of the action can be
>         performed by different functions without an explosion of parameter
>         passing, and so that actions that share some, but not all, of their
>         implementation (HiZ ops and blits, in this case) can be
>         implemented by
>         using a base class with virtual functions.  It's also possible
>         that in
>         the future, the blorp engine might be able to record the last
>         command it
>         executed, so that it can compare that to the command it's being
>         asked to
>         execute and avoid some redundant pipeline setup.  In the command
>         pattern, it is conventional to make the function that performs the
>         action a member of the command class and to call it "exec" or
>         "execute".  So from my point of view, this function name
>         actually *does*
>         have an implicit meaning.  I'm aware, of course, that most of my
>         fellow
>         Mesa developers don't share my respect for Gang of Four-style
>         design :)
>
>         (Note that in a strict implementation of the "command" pattern
>         there are
>         other auxiliary classes involved, but I thought that would be
>         way too
>         heavyweight for this purpose).
>
>
>     I believe that it is also typical in the command pattern for the
>     classes to have "command" in the name instead of "parameters."  At
>     least the examples in http://en.wikipedia.org/wiki/__Command_pattern
>     <http://en.wikipedia.org/wiki/Command_pattern> and my "Patterns in
>     Java" book suggest this.
>
>     For me, the advantage of patterns is rarely technical.  For me, the
>     advantage of patterns is in communication with other humans.  If a
>     piece of code says, "I'm an implementation of the factory pattern"
>     people will have a set of expectations about what's coming.  In some
>     sense they'll be familiar with the code before they even see it.
>
>     There was, by necessity, a lot of moving parts in MSAA patch series.
>     That combined with a slight deviation from the pattern (the
>     previously mentioned parameters vs. command naming) caused me to not
>     see the pattern.  For me, that defeated the improved communication
>     of pattern use.
>
>     Communication isn't just with other humans.  Perhaps if the class
>     had been called brw_blorp_blit_command you would have remembered
>     that you were using the command pattern while we were having the
>     review meeting. :)
>
>
> Yes, you're right.  That would have helped.
>
>
>
>             If I see foo->exec() or exec(foo) in a pipe of code, I have
>         to go
>             look at the declaration of foo to know what's going on.  If
>         I see
>             do_some_action(foo) it's a bit more obvious.
>
>
>         In this particular case (and in most uses of the command
>         pattern, IMHO),
>         the declaration is right next to the exec() call, so this isn't a
>         problem.  E.g.:
>
>             /* Do the blit */
>             brw_blorp_blit_params params(brw_context(ctx), src_mt, dst_mt,
>                                          srcX0, srcY0, dstX0, dstY0,
>         dstX1, dstY1,
>                                          mirror_x, mirror_y);
>             params.exec(intel);
>
>         I agree that it looks kind of hokey, though.  Other alternatives I
>         considered included:
>
>         - Make intel_context a class, and make executing a blorp action
>         a method
>         on that class, so that last line would have been something like
>         "intel->do_blorp_op(params);".  Incidentally, I think we would
>         get a lot
>         of benefits out of making brw_context, intel_context, and
>         gl_context a
>         class hierarchy; for example, macros like OUT_BATCH() would become
>         ordinary member functions, and we wouldn't have to do anywhere
>         near as
>         many explicit conversions between the three context types.
>           Also, the
>         virtual function tables that we currently code up explicitly
>         would be
>         automatically created by the compiler, so we would have much
>         less risk
>         of problems like forgetting to dispatch through the virtual function
>         table, forgetting to initialize a function pointer properly, or
>         initializing a function pointer at the wrong time.  Of course, this
>         would have been *way* too big a change to try to slip into this
>         patch
>         series.  By orders of magnitude.
>
>         - Make a base class to represent the Blorp engine, with a
>         derived class
>         for Gen6 and a derived class for Gen7.  The appropriate object
>         would be
>         created at context creation time.  Then, instead of calling
>         "params.exec(intel);", you would do "brw->blorp->exec(params);".  I
>         largely dismissed this option because I had already done so much
>         refactoring of the HiZ code that it seemed like it was time to
>         settle
>         down and actually implement some new functionality.  But I would
>         still
>         be open to it if people like the idea.
>
>
>     Wouldn't a more usual way to handle this kind of partitioning be
>     with an abstract factory?
>
> Can you elaborate?  IIRC, an abstract factory is for when component A
> needs to do object creation, but component B knows how to do object
> creation, so you create an abstract factory class with a pure virtual
> "create" method.  Component B instantiates a concrete factory and hands
> it off to component A, and then component A can use the factory to
> create the objects without needing to know details about how they are
> created.  It's not obvious to me how to map this pattern onto the
> situation we have with brw_blorp_params.

I was thinking you'd have an blorp_factory class with pure virtual 
create_blit_command and create_hiz_resolve_command methods.  The 
gen6_blorp_factory and gen7_blorp_factory classes would derive from 
blorp_factory.  The intelCreateContext would instantiate either a 
gen6_blorp_factory or a gen7_blorp_factory at context creation.  The 
rest of the architecture would remain pretty much the way you have it now.


More information about the mesa-dev mailing list