[Mesa-dev] State tracker pipe_surface woes...
jfonseca at vmware.com
Wed Sep 7 10:52:53 PDT 2011
----- Original Message -----
> Am 07.09.2011 07:33, schrieb Stéphane Marchesin:
> > 2011/9/2 Jose Fonseca <jfonseca at vmware.com>:
> >> ----- Original Message -----
> >>> Hi,
> >>> While debugging some code I ran across the following situation:
> >>> - pipe_context c1 is created
> >>> - pipe_surface s1 is created
> >>> - strb-> surface is set to s1 (s1's refcount goes up)
> >>> - pipe_context c1 is destroyed
> >>> - strb is destroyed
> >>> - strb->surface is destroyed (so s1's refcount is now 0 and we
> >>> want
> >>> to
> >>> destroy it)
> >>> At that point s1 references c1 which is not available any more,
> >>> so
> >>> when we try to call ctx->surface_destroy to destroy s1 we crash.
> >>> We discussed this a bit on IRC, and we agreed that the proper
> >>> solution, since surfaces outlive their context, is to make
> >>> surfaces
> >>> screen-bound instead. I'm going to implement that unless someone
> >>> objects.
> >>> As a side note, the same issue will happen with sampler_views, so
> >>> it'll get a similar fix.
> >> Sampler views and surfaces were previously objects bound to
> >> screen, and we changed that because of poor multithreading
> >> semantics. Per-context sampler views / render targets actually
> >> matches the 3D APIs semantics better, so I don't think that
> >> reverting is the solution.
> >> It looks to me that the issue here is that pipe_context should not
> >> be destroyed before the surfaces. strb->surface should only be
> >> used by one context, and should be destroyed before that context
> >> is destroyed.
> >> IIUC, strb matches GL renderbuffer semantics and can be shared by
> >> multiple context. If so, strb is treating pipe_surfaces as a
> >> entity shareable by contexts when really shouldn't.
> >> The solution is:
> >> - strb can only have pipe_resources, plus the key for the surface
> >> (face, level, etc)
> > Another bit I don't get: since pipe_resources don't have a pointer
> > to
> > the context, how do you go back to the corresponding
> > context/surface
> > when all you have is the pipe_resource?
> Short answer, you don't. Why do you need to?
> A pipe_surface is conceptually really just a means to supply the
> parameters to be used for rendering to a (color or depth)
> So you specify which level, layer(s) etc. of a resource will be used.
> That's all, analogous to pipe_sampler_view which does the same for
> texture sampling from a resource.
Yes. The statetracker either stores the pipe_surface somewhere, or re-creates the pipe_surfaces. And when recreating the driver may or not give the same pipe_surface pointer. The semantics are such that everything should just work regargless.
Is up to the pipe driver to ensure that when pipe->flush() is called, any pending drawing on a pipe_surface becomes visible in the parent pipe_resource, i.e, _all_ pipe_surfaces and pipe_sampler_views objects, created by all contexts will pick up the.
For pipe drivers where a pipe_surface is just a stateless structure, this is trivial to achieve. For pipe drivers where a pipe_surface has its own VRAM storage (due to unsupported formats/workarounds), this is achieved by queing a blit from that surface private VRAM to the pipe_resource VRAM at flush time.
More information about the mesa-dev