Hi,

The small attached patch adds a new drm ioctl to do surface allocation/deallocation on the radeon.

The reason to add a new ioctl is the following : since there are only 8 surfaces someone has to arbitrate between allocations by the ddx (color buffers) and from the dri (depth buffers). Doing it this way is more future proof than statically allocating them (for example, if we once do private z buffers or pbuffers these will be created/destroyed on the fly).

Any comments ? I'ts untested, but that's my first ioctl, so I wanted feedback (both on the idea and the implementation) before I build anything upon it.

Stephane

PS : I jumped to drm version 1.14 directly because hyperz already has 1.13

? linux/build
? linux/drm_pciids.h
Index: shared/radeon.h
===================================================================
RCS file: /cvs/dri/drm/shared/radeon.h,v
retrieving revision 1.33
diff -u -r1.33 radeon.h
--- shared/radeon.h     23 Oct 2004 06:25:56 -0000      1.33
+++ shared/radeon.h     8 Dec 2004 01:43:53 -0000
@@ -45,7 +45,7 @@
 #define DRIVER_DATE            "20020828"
 
 #define DRIVER_MAJOR           1
-#define DRIVER_MINOR           12
+#define DRIVER_MINOR           14
 #define DRIVER_PATCHLEVEL      0
 
 /* Interface history:
@@ -82,6 +82,7 @@
  *       and GL_EXT_blend_[func|equation]_separate on r200
  * 1.12- Add R300 CP microcode support - this just loads the CP on r300
  *       (No 3D support yet - just microcode loading).
+ * 1.14- Add R100/R200 surface allocation/free support
  */
 #define DRIVER_IOCTLS                                                       \
  [DRM_IOCTL_NR(DRM_IOCTL_DMA)]               = { radeon_cp_buffers,  1, 0 }, \
@@ -110,5 +111,7 @@
  [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)]   = { radeon_irq_emit,    1, 0 }, \
  [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)]   = { radeon_irq_wait,    1, 0 }, \
  [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SETPARAM)]   = { radeon_cp_setparam, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SURF_ALLOC)] = { radeon_surface_alloc,1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SURF_FREE)]  = { radeon_surface_free ,1, 0 }, \
 
 #endif
Index: shared/radeon_cp.c
===================================================================
RCS file: /cvs/dri/drm/shared/radeon_cp.c,v
retrieving revision 1.45
diff -u -r1.45 radeon_cp.c
--- shared/radeon_cp.c  23 Oct 2004 06:25:56 -0000      1.45
+++ shared/radeon_cp.c  8 Dec 2004 01:43:54 -0000
@@ -1519,6 +1519,8 @@
        radeon_cp_init_ring_buffer( dev, dev_priv );
 
        dev_priv->last_buf = 0;
+       
+       dev_priv->surfaces = 0;
 
        radeon_do_engine_reset( dev );
 
Index: shared/radeon_drm.h
===================================================================
RCS file: /cvs/dri/drm/shared/radeon_drm.h,v
retrieving revision 1.24
diff -u -r1.24 radeon_drm.h
--- shared/radeon_drm.h 23 Oct 2004 06:25:56 -0000      1.24
+++ shared/radeon_drm.h 8 Dec 2004 01:43:54 -0000
@@ -399,6 +399,8 @@
 #define DRM_RADEON_IRQ_WAIT   0x17
 #define DRM_RADEON_CP_RESUME  0x18
 #define DRM_RADEON_SETPARAM   0x19
+#define DRM_RADEON_SURF_ALLOC 0x20
+#define DRM_RADEON_SURF_FREE  0x21
 
 #define DRM_IOCTL_RADEON_CP_INIT    DRM_IOW( DRM_COMMAND_BASE + 
DRM_RADEON_CP_INIT, drm_radeon_init_t)
 #define DRM_IOCTL_RADEON_CP_START   DRM_IO(  DRM_COMMAND_BASE + 
DRM_RADEON_CP_START)
@@ -425,6 +427,8 @@
 #define DRM_IOCTL_RADEON_IRQ_WAIT   DRM_IOW( DRM_COMMAND_BASE + 
DRM_RADEON_IRQ_WAIT, drm_radeon_irq_wait_t)
 #define DRM_IOCTL_RADEON_CP_RESUME  DRM_IO(  DRM_COMMAND_BASE + 
DRM_RADEON_CP_RESUME)
 #define DRM_IOCTL_RADEON_SETPARAM   DRM_IOW( DRM_COMMAND_BASE + 
DRM_RADEON_SETPARAM, drm_radeon_setparam_t)
+#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOWR(DRM_COMMAND_BASE + 
DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
+#define DRM_IOCTL_RADEON_SURF_FREE  DRM_IOW( DRM_COMMAND_BASE + 
DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
 
 typedef struct drm_radeon_init {
        enum {
@@ -624,6 +628,18 @@
        int64_t      value;
 } drm_radeon_setparam_t;
 
+/* 1.14: Clients can allocate/free a surface
+ */
+
+typedef struct drm_radeon_surface_alloc {
+       int surface;
+} drm_radeon_surface_alloc_t;
+
+typedef struct drm_radeon_surface_free {
+       int surface;
+} drm_radeon_surface_free_t;
+
+
 #define RADEON_SETPARAM_FB_LOCATION    1 /* determined framebuffer location */
 
 
Index: shared/radeon_drv.h
===================================================================
RCS file: /cvs/dri/drm/shared/radeon_drv.h,v
retrieving revision 1.37
diff -u -r1.37 radeon_drv.h
--- shared/radeon_drv.h 9 Nov 2004 00:54:19 -0000       1.37
+++ shared/radeon_drv.h 8 Dec 2004 01:43:55 -0000
@@ -185,6 +185,8 @@
        struct mem_block *gart_heap;
        struct mem_block *fb_heap;
 
+       u32 surfaces;
+       
        /* SW interrupt */
        wait_queue_head_t swi_queue;
        atomic_t swi_emitted;
@@ -239,6 +241,8 @@
 extern int radeon_mem_init_heap( DRM_IOCTL_ARGS );
 extern void radeon_mem_takedown( struct mem_block **heap );
 extern void radeon_mem_release( DRMFILE filp, struct mem_block *heap );
+extern int radeon_surface_alloc( DRM_IOCTL_ARGS );
+extern int radeon_surface_free( DRM_IOCTL_ARGS );
 
                                /* radeon_irq.c */
 extern int radeon_irq_emit( DRM_IOCTL_ARGS );
Index: shared/radeon_state.c
===================================================================
RCS file: /cvs/dri/drm/shared/radeon_state.c,v
retrieving revision 1.39
diff -u -r1.39 radeon_state.c
--- shared/radeon_state.c       23 Oct 2004 06:25:56 -0000      1.39
+++ shared/radeon_state.c       8 Dec 2004 01:43:56 -0000
@@ -1544,6 +1544,61 @@
  * IOCTL functions
  */
 
+int radeon_surface_alloc( DRM_IOCTL_ARGS )
+{
+       DRM_DEVICE;
+       drm_radeon_private_t *dev_priv = dev->dev_private;
+       drm_radeon_surface_alloc_t alloc;
+       int i;
+
+       if ( !dev_priv ) {
+               DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+               return DRM_ERR(EINVAL);
+       }
+
+       DRM_COPY_FROM_USER_IOCTL( alloc, (drm_radeon_surface_alloc_t __user 
*)data,
+                                 sizeof(alloc) );
+
+       // allocate the surface
+       for(i=0;i<8;i++)
+               if (!(dev_priv->surfaces&(1<<i)))
+                       break;
+
+       if (i>=8)
+               return DRM_ERR(ENOMEM);
+       else
+               dev_priv->surfaces&=(1<<i);
+       
+       if ( DRM_COPY_TO_USER( &alloc.surface, &i, 
+                              sizeof(int) ) ) {
+               DRM_ERROR( "copy_to_user\n" );
+               return DRM_ERR(EFAULT);
+       }
+       
+       return 0;
+}
+
+int radeon_surface_free( DRM_IOCTL_ARGS )
+{
+       DRM_DEVICE;
+       drm_radeon_private_t *dev_priv = dev->dev_private;
+       drm_radeon_surface_free_t memfree;
+
+       if ( !dev_priv ) {
+               DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+               return DRM_ERR(EINVAL);
+       }
+
+
+       DRM_COPY_FROM_USER_IOCTL( memfree, (drm_radeon_mem_free_t __user *)data,
+                                 sizeof(memfree) );
+
+       dev_priv->surfaces&= (~(1<<memfree.surface));
+       
+       return 0;
+}
+
+
 int radeon_cp_clear( DRM_IOCTL_ARGS )
 {
        DRM_DEVICE;

Reply via email to