radeon: move code around putting emit into cs
authorDave Airlie <airlied@redhat.com>
Tue, 29 Jul 2008 08:05:11 +0000 (18:05 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 29 Jul 2008 08:05:11 +0000 (18:05 +1000)
linux-core/radeon_gem.c
shared-core/radeon_cs.c
shared-core/radeon_drv.h

index 859c165..9d122ac 100644 (file)
@@ -700,7 +700,7 @@ int radeon_gem_object_pin(struct drm_gem_object *obj,
 
 #define RADEON_NUM_IB (RADEON_IB_MEMORY / RADEON_IB_SIZE)
 
-int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords)
+int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords, uint32_t *card_offset)
 {
        int i, index = -1;
        int ret;
@@ -738,6 +738,15 @@ int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords)
        if (dwords > RADEON_IB_SIZE / sizeof(uint32_t))
                return -EINVAL;
 
+       ret = drm_bo_do_validate(dev_priv->ib_objs[index]->bo, 0,
+                                DRM_BO_FLAG_NO_EVICT,
+                                0, 0, NULL);
+       if (ret) {
+               DRM_ERROR("Failed to validate IB %d\n", index);
+               return -EINVAL;
+       }
+               
+       *card_offset = dev_priv->gart_vm_start + dev_priv->ib_objs[index]->bo->offset;
        *ib = dev_priv->ib_objs[index]->kmap.virtual;
        dev_priv->ib_alloc_bitmap |= (1 << i);
        return 0;
@@ -754,24 +763,6 @@ static void radeon_gem_ib_free(struct drm_device *dev, void *ib, uint32_t dwords
        for (i = 0; i < RADEON_NUM_IB; i++) {
 
                if (dev_priv->ib_objs[i]->kmap.virtual == ib) {
-                       ret = drm_bo_do_validate(dev_priv->ib_objs[i]->bo, 0,
-                                DRM_BO_FLAG_NO_EVICT,
-                                0, 0, NULL);
-                       if (ret)
-                               DRM_ERROR("FAiled to validate\n");
-
-                       DRM_DEBUG("validated IB %x, %d\n", dev_priv->ib_objs[i]->bo->offset, dwords);
-                       BEGIN_RING(4);
-                       
-                       OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
-                       OUT_RING(dev_priv->gart_vm_start + dev_priv->ib_objs[i]->bo->offset);
-                       OUT_RING(dwords);
-                       OUT_RING(CP_PACKET2());
-
-                       ADVANCE_RING();
-
-                       COMMIT_RING();
-
                        /* emit a fence object */
                        ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence);
                        if (ret) {
index f01334b..33a8ccd 100644 (file)
 
 int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
 {
-       struct drm_radeon_private *radeon = dev->dev_private;
+       struct drm_radeon_private *dev_priv = dev->dev_private;
        struct drm_radeon_cs *cs = data;
        uint32_t *packets = NULL;
        uint32_t cs_id;
+       uint32_t card_offset;
        void *ib = NULL;
        long size;
        int r;
+       RING_LOCALS;
 
        /* set command stream id to 0 which is fake id */
        cs_id = 0;
        DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t));
 
-       if (radeon == NULL) {
+       if (dev_priv == NULL) {
                DRM_ERROR("called with no initialization\n");
                return -EINVAL;
        }
@@ -68,22 +70,31 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
                goto out;
        }
        /* get ib */
-       r = radeon->cs.ib_get(dev, &ib, cs->dwords);
+       r = dev_priv->cs.ib_get(dev, &ib, cs->dwords, &card_offset);
        if (r) {
                goto out;
        }
 
        /* now parse command stream */
-       r = radeon->cs.parse(dev, fpriv, ib, packets, cs->dwords);
+       r = dev_priv->cs.parse(dev, fpriv, ib, packets, cs->dwords);
        if (r) {
                goto out;
        }
 
+       BEGIN_RING(4);
+       OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
+       OUT_RING(card_offset);
+       OUT_RING(cs->dwords);
+       OUT_RING(CP_PACKET2());
+       ADVANCE_RING();
+
        /* emit cs id sequence */
-       radeon->cs.id_emit(dev, &cs_id);
+       dev_priv->cs.id_emit(dev, &cs_id);
+       COMMIT_RING();
+
        DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t));
 out:
-       radeon->cs.ib_free(dev, ib, cs->dwords);
+       dev_priv->cs.ib_free(dev, ib, cs->dwords);
        drm_free(packets, size, DRM_MEM_DRIVER);
        return r;
 }
@@ -97,8 +108,8 @@ static int radeon_nomm_relocate(struct drm_device *dev, struct drm_file *file_pr
 #define RELOC_SIZE 2
 #define RADEON_2D_OFFSET_MASK 0x3fffff
 
-static __inline__ int radeon_cs_relocate_offset(struct drm_device *dev, struct drm_file *file_priv,
-                                               uint32_t *packets, uint32_t offset_dw)
+static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct drm_file *file_priv,
+                                                uint32_t *packets, uint32_t offset_dw)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
        uint32_t hdr = packets[offset_dw];
@@ -107,7 +118,7 @@ static __inline__ int radeon_cs_relocate_offset(struct drm_device *dev, struct d
        uint32_t packet3_hdr = packets[offset_dw+2];
        uint32_t tmp, offset;
        int ret;
-       
+
        /* this is too strict we may want to expand the length in the future and have
         old kernels ignore it. */ 
        if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) {
@@ -132,8 +143,6 @@ static __inline__ int radeon_cs_relocate_offset(struct drm_device *dev, struct d
        case R300_RB3D_DEPTHOFFSET:
        case R300_TX_OFFSET_0:
        case R300_TX_OFFSET_0+4:
-               offset = packets[offset_dw + 3];
-
                ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset);
                if (ret)
                        return ret;
@@ -151,6 +160,40 @@ static __inline__ int radeon_cs_relocate_offset(struct drm_device *dev, struct d
 
        return 0;
 }
+
+static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *file_priv,
+                                     uint32_t *packets, uint32_t offset_dw)
+{
+       drm_radeon_private_t *dev_priv = dev->dev_private;
+       uint32_t hdr = packets[offset_dw];
+       int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16;
+       uint32_t reg = hdr & 0xff00;
+       uint32_t offset, val, tmp;
+       int ret;
+
+       switch(reg) {
+       case RADEON_CNTL_HOSTDATA_BLT:
+       {
+               val = packets[offset_dw + 2];
+               ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + num_dw + 2, &offset);
+               if (ret)
+                       return ret;
+
+               tmp = (val & RADEON_2D_OFFSET_MASK) << 10;
+               val &= ~RADEON_2D_OFFSET_MASK;
+               offset += tmp;
+               offset >>= 10;
+               val |= offset;
+
+               DRM_ERROR("New offset %x %x %x\n", packets[offset_dw+2], val, offset);
+               packets[offset_dw + 2] = val;
+       }
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
 static __inline__ int radeon_cs_check_offset(struct drm_device *dev,
                                             uint32_t reg, uint32_t val)
 {
@@ -207,7 +250,7 @@ int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv,
                                        return -EINVAL;
                                }
 
-                               ret = radeon_cs_relocate_offset(dev, file_priv, packets, offset_dw);
+                               ret = radeon_cs_relocate_packet0(dev, file_priv, packets, offset_dw);
                                if (ret)
                                        return ret;
                                DRM_DEBUG("need to relocate %x %d\n", reg, flags);
@@ -256,14 +299,9 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv,
                        
                        switch(reg) {
                        case RADEON_CNTL_HOSTDATA_BLT:
-                       {
-                               uint32_t offset;
-                               offset = packets[count_dw+2] & ((1 << 22) - 1);
-                               offset <<= 10;
-                               DRM_ERROR("Offset check for Packet 3 %x %x\n", reg, offset);
-                               /* okay it should be followed by a NOP */
+                               radeon_cs_relocate_packet3(dev, file_priv, packets, count_dw);
                                break;
-                       }
+
                        case RADEON_CNTL_BITBLT_MULTI:
                        case RADEON_3D_LOAD_VBPNTR:     /* load vertex array pointers */
                        case RADEON_CP_INDX_BUFFER:
index f79eade..e55a969 100644 (file)
@@ -300,11 +300,11 @@ struct drm_radeon_cs_priv {
        /* this ib handling callback are for hidding memory manager drm
         * from memory manager less drm, free have to emit ib discard
         * sequence into the ring */
-       int (*ib_get)(struct drm_device *dev, void **ib, uint32_t dwords);
+       int (*ib_get)(struct drm_device *dev, void **ib, uint32_t dwords, uint32_t *card_offset);
        uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib);
        void (*ib_free)(struct drm_device *dev, void *ib, uint32_t dwords);
        /* do a relocation either MM or non-MM */
-       bool (*relocate)(struct drm_device *dev, struct drm_file *file_priv,
+       int (*relocate)(struct drm_device *dev, struct drm_file *file_priv,
                         uint32_t *reloc, uint32_t *offset);
 };