Merge branch 'master' of git+ssh://git.freedesktop.org/git/mesa/drm into modesetting-101
authorAlan Hourihane <alanh@tungstengraphics.com>
Tue, 26 Feb 2008 15:42:41 +0000 (15:42 +0000)
committerAlan Hourihane <alanh@tungstengraphics.com>
Tue, 26 Feb 2008 15:42:41 +0000 (15:42 +0000)
Conflicts:

shared-core/i915_dma.c

1  2 
linux-core/i915_drv.c
shared-core/i915_dma.c
shared-core/radeon_state.c

Simple merge
@@@ -1032,48 -1109,146 +1069,146 @@@ int i915_validate_buffer_list(struct dr
                        DRM_MEMORYBARRIER();
                }
  
-               rep.ret = drm_bo_handle_validate(file_priv, req->bo_req.handle,
-                                                req->bo_req.flags, req->bo_req.mask,
-                                                req->bo_req.hint,
-                                                req->bo_req.fence_class, 0,
-                                                &rep.bo_info,
-                                                &buffers[buf_count].buffer);
+               ret = drm_bo_handle_validate(file_priv, req->bo_req.handle,
+                                            req->bo_req.flags, req->bo_req.mask,
+                                            req->bo_req.hint,
+                                            req->bo_req.fence_class, 0,
+                                            &item->rep,
+                                            &item->buffer);
  
-               if (rep.ret) {
-                       DRM_ERROR("error on handle validate %d\n", rep.ret);
+               if (ret) {
+                       DRM_ERROR("error on handle validate %d\n", ret);
                        goto out_err;
                }
 -      struct drm_device *dev = file_priv->head->dev;
+               buf_count++;
+               ret = i915_check_presumed(&arg, item->buffer,
+                                         (uint32_t __user *)
+                                         (unsigned long) data,
+                                         &item->presumed_offset_correct);
+               if (ret)
+                       goto out_err;
+               data = arg.next;
+       } while (data != 0);
+ out_err:
+       *num_buffers = buf_count;
+       item->ret = (ret != -EAGAIN) ? ret : 0;
+       return ret;
+ }
+ /*
+  * Remove all buffers from the unfenced list.
+  * If the execbuffer operation was aborted, for example due to a signal,
+  * this also make sure that buffers retain their original state and
+  * fence pointers.
+  * Copy back buffer information to user-space unless we were interrupted
+  * by a signal. In which case the IOCTL must be rerun.
+  */
+ static int i915_handle_copyback(struct drm_device *dev,
+                               struct drm_i915_validate_buffer *buffers,
+                               unsigned int num_buffers, int ret)
+ {
+       int err = ret;
+       int i;
+       struct drm_i915_op_arg arg;
+       if (ret)
+               drm_putback_buffer_objects(dev);
+       if (ret != -EAGAIN) {
+               for (i = 0; i < num_buffers; ++i) {
+                       arg.handled = 1;
+                       arg.d.rep.ret = buffers->ret;
+                       arg.d.rep.bo_info = buffers->rep;
+                       if (__copy_to_user(buffers->data, &arg, sizeof(arg)))
+                               err = -EFAULT;
+                       buffers++;
+               }
+       }
+       return err;
+ }
+ /*
+  * Create a fence object, and if that fails, pretend that everything is
+  * OK and just idle the GPU.
+  */
+ void i915_fence_or_sync(struct drm_file *file_priv,
+                       uint32_t fence_flags,
+                       struct drm_fence_arg *fence_arg,
+                       struct drm_fence_object **fence_p)
+ {
++      struct drm_device *dev = file_priv->minor->dev;
+       int ret;
+       struct drm_fence_object *fence;
+       ret = drm_fence_buffer_objects(dev, NULL, fence_flags,
+                        NULL, &fence);
+       if (ret) {
                /*
-                * If the user provided a presumed offset hint, check whether
-                * the buffer is in the same place, if so, relocations relative to
-                * this buffer need not be performed
+                * Fence creation failed.
+                * Fall back to synchronous operation and idle the engine.
                 */
-               if ((req->bo_req.hint & DRM_BO_HINT_PRESUMED_OFFSET) &&
-                   buffers[buf_count].buffer->offset == req->bo_req.presumed_offset) {
-                       buffers[buf_count].presumed_offset_correct = 1;
-               }
  
-               next = arg.next;
-               arg.handled = 1;
-               arg.d.rep = rep;
+               (void) i915_emit_mi_flush(dev, MI_READ_FLUSH);
+               (void) i915_quiescent(dev);
  
-               if (copy_to_user((void __user *)(unsigned long)data, &arg, sizeof(arg)))
-                       return -EFAULT;
+               if (!(fence_flags & DRM_FENCE_FLAG_NO_USER)) {
  
-               data = next;
-               buf_count++;
+                       /*
+                        * Communicate to user-space that
+                        * fence creation has failed and that
+                        * the engine is idle.
+                        */
  
-       } while (next != 0);
-       *num_buffers = buf_count;
-       return 0;
- out_err:
-       mutex_lock(&dev->struct_mutex);
-       i915_dereference_buffers_locked(buffers, buf_count);
-       mutex_unlock(&dev->struct_mutex);
-       *num_buffers = 0;
-       return (ret) ? ret : rep.ret;
+                       fence_arg->handle = ~0;
+                       fence_arg->error = ret;
+               }
+               drm_putback_buffer_objects(dev);
+               if (fence_p)
+                   *fence_p = NULL;
+               return;
+       }
+       if (!(fence_flags & DRM_FENCE_FLAG_NO_USER)) {
+               ret = drm_fence_add_user_object(file_priv, fence,
+                                               fence_flags &
+                                               DRM_FENCE_FLAG_SHAREABLE);
+               if (!ret)
+                       drm_fence_fill_arg(fence, fence_arg);
+               else {
+                       /*
+                        * Fence user object creation failed.
+                        * We must idle the engine here as well, as user-
+                        * space expects a fence object to wait on. Since we
+                        * have a fence object we wait for it to signal
+                        * to indicate engine "sufficiently" idle.
+                        */
+                       (void) drm_fence_object_wait(fence, 0, 1,
+                                                    fence->type);
+                       drm_fence_usage_deref_unlocked(&fence);
+                       fence_arg->handle = ~0;
+                       fence_arg->error = ret;
+               }
+       }
+       if (fence_p)
+               *fence_p = fence;
+       else if (fence)
+               drm_fence_usage_deref_unlocked(&fence);
  }
  
  static int i915_execbuffer(struct drm_device *dev, void *data,
                           struct drm_file *file_priv)
  {
Simple merge