+
+/**
+ * \brief Query DRI image loader to obtain a DRIdrawable's buffers.
+ *
+ * To determine which DRI buffers to request, examine the renderbuffers
+ * attached to the drawable's framebuffer. Then request the buffers from
+ * the image loader
+ *
+ * This is called from intel_update_renderbuffers().
+ *
+ * \param drawable Drawable whose buffers are queried.
+ * \param buffers [out] List of buffers returned by DRI2 query.
+ * \param buffer_count [out] Number of buffers returned.
+ *
+ * \see intel_update_renderbuffers()
+ */
+
+static void
+intel_update_image_buffer(struct brw_context *intel,
+ __DRIdrawable *drawable,
+ struct intel_renderbuffer *rb,
+ __DRIimage *buffer,
+ enum __DRIimageBufferMask buffer_type)
+{
+ struct intel_region *region = buffer->region;
+
+ if (!rb || !region)
+ return;
+
+ unsigned num_samples = rb->Base.Base.NumSamples;
+
+ /* Check and see if we're already bound to the right
+ * buffer object
+ */
+ if (num_samples == 0) {
+ if (rb->mt &&
+ rb->mt->region &&
+ rb->mt->region->bo == region->bo)
+ return;
+ } else {
+ if (rb->mt &&
+ rb->mt->singlesample_mt &&
+ rb->mt->singlesample_mt->region &&
+ rb->mt->singlesample_mt->region->bo == region->bo)
+ return;
+ }
+
+ intel_miptree_release(&rb->mt);
+ rb->mt = intel_miptree_create_for_image_buffer(intel,
+ buffer_type,
+ intel_rb_format(rb),
+ num_samples,
+ region);
+}
+
+static void
+intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable)
+{
+ struct gl_framebuffer *fb = drawable->driverPrivate;
+ __DRIscreen *screen = brw->intelScreen->driScrnPriv;
+ struct intel_renderbuffer *front_rb;
+ struct intel_renderbuffer *back_rb;
+ struct __DRIimageList images;
+ unsigned int format;
+ uint32_t buffer_mask = 0;
+
+ front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+ back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
+
+ if (back_rb)
+ format = intel_rb_format(back_rb);
+ else if (front_rb)
+ format = intel_rb_format(front_rb);
+ else
+ return;
+
+ if ((brw->is_front_buffer_rendering || brw->is_front_buffer_reading || !back_rb) && front_rb)
+ buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
+
+ if (back_rb)
+ buffer_mask |= __DRI_IMAGE_BUFFER_BACK;
+
+ (*screen->image.loader->getBuffers) (drawable,
+ driGLFormatToImageFormat(format),
+ &drawable->dri2.stamp,
+ drawable->loaderPrivate,
+ buffer_mask,
+ &images);
+
+ if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
+ drawable->w = images.front->width;
+ drawable->h = images.front->height;
+ intel_update_image_buffer(brw,
+ drawable,
+ front_rb,
+ images.front,
+ __DRI_IMAGE_BUFFER_FRONT);
+ }
+ if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
+ drawable->w = images.back->width;
+ drawable->h = images.back->height;
+ intel_update_image_buffer(brw,
+ drawable,
+ back_rb,
+ images.back,
+ __DRI_IMAGE_BUFFER_BACK);
+ }
+}