Keith Packard wrote: >On Fri, 2007-12-21 at 13:40 +0100, Thomas Hellström wrote: > > > >>// Change only the RW flags, and set them to "Write" >>validate(bo, DRM_BO_FLAG_WRITE , DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE) >>Render to buffer object. >>// Change only the RW flags, and set them to "READ" >>validate(bo, DRM_BO_FLAG_READ , DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE) >>Use as a texture. >> >>Is this sufficient to do what you're after? >> >> > >From the application's perspective, this is descriptive enough, yes. The >problem is that inside the DRM, this information is not available after >the operation has been queued. > >Here's a concrete example that might help explain what I was thinking. > > Draw to surface "A" from surface "B". > paint B onto A > emit breadcrumb 1 > emit IRQ > Draw to surface "C" from surface "A". > paint A onto C > emit breadcrumb 2 > emit IRQ > >Right now, waiting for breadcrumb 1 is not sufficient to be able to use >A to paint onto C. We must emit an MI_FLUSH, so we need to know after >emiting fence 1 that A will be written and must be flushed before being >read. I think what I want is this: > > paint B onto A > emit breadcrumb 1 > emit IRQ > > flush A > emit breadcrumb 1.5 > emit IRQ > > paint A onto C > emit breadcrumb 2 > emit IRQ > >sticking a 'flush/breadcrumb/irq' sequence in the middle means I can >know that a flush operation has occurred, and go through and clean any >buffers which were written but not flushed. But, I have to know which >buffers those are, and record which breadcrumb value will be sufficient >to flush them. > >The only case where I'll have to wait for the flush operation is when I >want to unbind the object from the GTT; other than that, the flushes can >all go in-line. > > > OK. This is a case that is a bit trickier. If this were a single application (non-shareable) buffer object we'd resolve this from user-space.
The way I would do this with a small extension to the current implementation is to implement a DRM_I915_FENCE_TYPE_READ fence type and a DRM_I915_FENCE_TYPE_WRITE fence type, which are triggered by the corresponding buffer object proposed_flags. Now, when you want to paint A onto C, you validate for a READ operation, and the WRITE flag is cleared. The validate code will detect that the previous fence_type included the DRM_I915_FENCE_TYPE_WRITE flag which we now want to clear and will force a buffer idle during validation. (This is done in drm_buffer_object_validate below the comment "We're switching command submission mechanism....") This will guarantee that the render results are correct, but will wait for buffer idle during validation, which is, as you say, not what you want since that will partially drain the hw command queue and block other command submission. To further optimize this situation we'd need a driver-specific incompatible_fence_class_or_type() function which is called instead of drm_bo_wait() When validate needs to serialize. In your case it would (unless the buffer is already idle) emit a write MI_FLUSH and a new breadcrumb to the command stream, and then re-emit the fence object the buffer was pointing to with type (old_fence_type & ~DRM_I915_FENCE_TYPE_WRITE) and native_type DRM_i915_FENCE_TYPE_WRITE (native_type means that this fence_type is implicitly signaled when the EXE type is signaled). re-emitting can be done with drm_fence_object_emit() But I've never tested it in this context. This scheme would not work is a buffer is validated for READ and WRITE at the same time, and there might be better solutions. The needed changes to the current implementation are minimal, though. /Thomas ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel