r600g: deobfuscate async DMA code
authorMarek Olšák <marek.olsak@amd.com>
Mon, 17 Mar 2014 00:18:43 +0000 (01:18 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 20 Mar 2014 17:56:11 +0000 (18:56 +0100)
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
src/gallium/drivers/r600/evergreen_hw_context.c
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/evergreend.h
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600d.h

index e43eacc9a0ae29e9a07f52d84ec01de53502e372..a47461c20ea743bbad4d98c6e86dc17464a807f7 100644 (file)
@@ -50,19 +50,19 @@ void evergreen_dma_copy(struct r600_context *rctx,
        src_offset += r600_resource_va(&rctx->screen->b.b, src);
 
        /* see if we use dword or byte copy */
-       if (!(dst_offset & 0x3) && !(src_offset & 0x3) && !(size & 0x3)) {
+       if (!(dst_offset % 4) && !(src_offset % 4) && !(size % 4)) {
                size >>= 2;
-               sub_cmd = 0x00;
+               sub_cmd = EG_DMA_COPY_DWORD_ALIGNED;
                shift = 2;
        } else {
-               sub_cmd = 0x40;
+               sub_cmd = EG_DMA_COPY_BYTE_ALIGNED;
                shift = 0;
        }
-       ncopy = (size / 0x000fffff) + !!(size % 0x000fffff);
+       ncopy = (size / EG_DMA_COPY_MAX_SIZE) + !!(size % EG_DMA_COPY_MAX_SIZE);
 
        r600_need_dma_space(&rctx->b, ncopy * 5);
        for (i = 0; i < ncopy; i++) {
-               csize = size < 0x000fffff ? size : 0x000fffff;
+               csize = size < EG_DMA_COPY_MAX_SIZE ? size : EG_DMA_COPY_MAX_SIZE;
                /* emit reloc before writting cs so that cs is always in consistent state */
                r600_context_bo_reloc(&rctx->b, &rctx->b.rings.dma, rsrc, RADEON_USAGE_READ,
                                      RADEON_PRIO_MIN);
index fb3450674f11273af7b2c54ca4c3c78962d29bc4..11cd76772af9e377c4383b16f107b85331c0ca9c 100644 (file)
@@ -3233,15 +3233,15 @@ static void evergreen_dma_copy_tile(struct r600_context *rctx,
                non_disp_tiling = 1;
 
        y = 0;
-       sub_cmd = 0x8;
+       sub_cmd = EG_DMA_COPY_TILED;
        lbpp = util_logbase2(bpp);
-       pitch_tile_max = ((pitch / bpp) >> 3) - 1;
+       pitch_tile_max = ((pitch / bpp) / 8) - 1;
        nbanks = eg_num_banks(rctx->screen->b.tiling_info.num_banks);
 
        if (dst_mode == RADEON_SURF_MODE_LINEAR) {
                /* T2L */
                array_mode = evergreen_array_mode(src_mode);
-               slice_tile_max = (rsrc->surface.level[src_level].nblk_x * rsrc->surface.level[src_level].nblk_y) >> 6;
+               slice_tile_max = (rsrc->surface.level[src_level].nblk_x * rsrc->surface.level[src_level].nblk_y) / (8*8);
                slice_tile_max = slice_tile_max ? slice_tile_max - 1 : 0;
                /* linear height must be the same as the slice tile max height, it's ok even
                 * if the linear destination/source have smaller heigh as the size of the
@@ -3266,7 +3266,7 @@ static void evergreen_dma_copy_tile(struct r600_context *rctx,
        } else {
                /* L2T */
                array_mode = evergreen_array_mode(dst_mode);
-               slice_tile_max = (rdst->surface.level[dst_level].nblk_x * rdst->surface.level[dst_level].nblk_y) >> 6;
+               slice_tile_max = (rdst->surface.level[dst_level].nblk_x * rdst->surface.level[dst_level].nblk_y) / (8*8);
                slice_tile_max = slice_tile_max ? slice_tile_max - 1 : 0;
                /* linear height must be the same as the slice tile max height, it's ok even
                 * if the linear destination/source have smaller heigh as the size of the
@@ -3290,16 +3290,16 @@ static void evergreen_dma_copy_tile(struct r600_context *rctx,
                addr += r600_resource_va(&rctx->screen->b.b, src);
        }
 
-       size = (copy_height * pitch) >> 2;
-       ncopy = (size / 0x000fffff) + !!(size % 0x000fffff);
+       size = (copy_height * pitch) / 4;
+       ncopy = (size / EG_DMA_COPY_MAX_SIZE) + !!(size % EG_DMA_COPY_MAX_SIZE);
        r600_need_dma_space(&rctx->b, ncopy * 9);
 
        for (i = 0; i < ncopy; i++) {
                cheight = copy_height;
-               if (((cheight * pitch) >> 2) > 0x000fffff) {
-                       cheight = (0x000fffff << 2) / pitch;
+               if (((cheight * pitch) / 4) > EG_DMA_COPY_MAX_SIZE) {
+                       cheight = (EG_DMA_COPY_MAX_SIZE * 4) / pitch;
                }
-               size = (cheight * pitch) >> 2;
+               size = (cheight * pitch) / 4;
                /* emit reloc before writting cs so that cs is always in consistent state */
                r600_context_bo_reloc(&rctx->b, &rctx->b.rings.dma, &rsrc->resource,
                                      RADEON_USAGE_READ, RADEON_PRIO_MIN);
@@ -3381,7 +3381,7 @@ static void evergreen_dma_blit(struct pipe_context *ctx,
        /* the x test here are currently useless (because we don't support partial blit)
         * but keep them around so we don't forget about those
         */
-       if ((src_pitch & 0x7) || (src_box->x & 0x7) || (dst_x & 0x7) || (src_box->y & 0x7) || (dst_y & 0x7)) {
+       if (src_pitch % 8 || src_box->x % 8 || dst_x % 8 || src_box->y % 8 || dst_y % 8) {
                goto fallback;
        }
 
index 986fd16f1bab13a437e0c4106f681270165d5b38..9fde18432fc3553e4a0b27fbdb835c4e4dce4a38 100644 (file)
 /* async DMA Packet types */
 #define    DMA_PACKET_WRITE                     0x2
 #define    DMA_PACKET_COPY                      0x3
+#define    EG_DMA_COPY_MAX_SIZE                        0xfffff
+#define    EG_DMA_COPY_DWORD_ALIGNED           0x00
+#define    EG_DMA_COPY_BYTE_ALIGNED            0x40
+#define    EG_DMA_COPY_TILED                   0x8
 #define    DMA_PACKET_INDIRECT_BUFFER           0x4
 #define    DMA_PACKET_SEMAPHORE                 0x5
 #define    DMA_PACKET_FENCE                     0x6
index eb5500e29e57ceb64a8353a48ba0ede2c7b38180..267b326a511958e32ae1fc55ddceb9b45b6a083b 100644 (file)
@@ -448,7 +448,7 @@ void r600_dma_copy(struct r600_context *rctx,
                uint64_t size)
 {
        struct radeon_winsys_cs *cs = rctx->b.rings.dma.cs;
-       unsigned i, ncopy, csize, shift;
+       unsigned i, ncopy, csize;
        struct r600_resource *rdst = (struct r600_resource*)dst;
        struct r600_resource *rsrc = (struct r600_resource*)src;
 
@@ -458,13 +458,12 @@ void r600_dma_copy(struct r600_context *rctx,
        util_range_add(&rdst->valid_buffer_range, dst_offset,
                       dst_offset + size);
 
-       size >>= 2;
-       shift = 2;
-       ncopy = (size / 0xffff) + !!(size % 0xffff);
+       size >>= 2; /* convert to dwords */
+       ncopy = (size / R600_DMA_COPY_MAX_SIZE_DW) + !!(size % R600_DMA_COPY_MAX_SIZE_DW);
 
        r600_need_dma_space(&rctx->b, ncopy * 5);
        for (i = 0; i < ncopy; i++) {
-               csize = size < 0xffff ? size : 0xffff;
+               csize = size < R600_DMA_COPY_MAX_SIZE_DW ? size : R600_DMA_COPY_MAX_SIZE_DW;
                /* emit reloc before writting cs so that cs is always in consistent state */
                r600_context_bo_reloc(&rctx->b, &rctx->b.rings.dma, rsrc, RADEON_USAGE_READ,
                                      RADEON_PRIO_MIN);
@@ -475,8 +474,8 @@ void r600_dma_copy(struct r600_context *rctx,
                cs->buf[cs->cdw++] = src_offset & 0xfffffffc;
                cs->buf[cs->cdw++] = (dst_offset >> 32UL) & 0xff;
                cs->buf[cs->cdw++] = (src_offset >> 32UL) & 0xff;
-               dst_offset += csize << shift;
-               src_offset += csize << shift;
+               dst_offset += csize << 2;
+               src_offset += csize << 2;
                size -= csize;
        }
 }
index 4aa379826fd5440c6ba585b4c0a3ba473984a11c..d87caf896697487432f44f6eeb261923e81f6296 100644 (file)
@@ -2802,12 +2802,12 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
 
        y = 0;
        lbpp = util_logbase2(bpp);
-       pitch_tile_max = ((pitch / bpp) >> 3) - 1;
+       pitch_tile_max = ((pitch / bpp) / 8) - 1;
 
        if (dst_mode == RADEON_SURF_MODE_LINEAR) {
                /* T2L */
                array_mode = r600_array_mode(src_mode);
-               slice_tile_max = (rsrc->surface.level[src_level].nblk_x * rsrc->surface.level[src_level].nblk_y) >> 6;
+               slice_tile_max = (rsrc->surface.level[src_level].nblk_x * rsrc->surface.level[src_level].nblk_y) / (8*8);
                slice_tile_max = slice_tile_max ? slice_tile_max - 1 : 0;
                /* linear height must be the same as the slice tile max height, it's ok even
                 * if the linear destination/source have smaller heigh as the size of the
@@ -2826,7 +2826,7 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
        } else {
                /* L2T */
                array_mode = r600_array_mode(dst_mode);
-               slice_tile_max = (rdst->surface.level[dst_level].nblk_x * rdst->surface.level[dst_level].nblk_y) >> 6;
+               slice_tile_max = (rdst->surface.level[dst_level].nblk_x * rdst->surface.level[dst_level].nblk_y) / (8*8);
                slice_tile_max = slice_tile_max ? slice_tile_max - 1 : 0;
                /* linear height must be the same as the slice tile max height, it's ok even
                 * if the linear destination/source have smaller heigh as the size of the
@@ -2844,20 +2844,20 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
                addr += src_y * pitch + src_x * bpp;
        }
        /* check that we are in dw/base alignment constraint */
-       if ((addr & 0x3) || (base & 0xff)) {
+       if (addr % 4 || base % 256) {
                return FALSE;
        }
 
        /* It's a r6xx/r7xx limitation, the blit must be on 8 boundary for number
         * line in the blit. Compute max 8 line we can copy in the size limit
         */
-       cheight = ((0x0000ffff << 2) / pitch) & 0xfffffff8;
+       cheight = ((R600_DMA_COPY_MAX_SIZE_DW * 4) / pitch) & 0xfffffff8;
        ncopy = (copy_height / cheight) + !!(copy_height % cheight);
        r600_need_dma_space(&rctx->b, ncopy * 7);
 
        for (i = 0; i < ncopy; i++) {
                cheight = cheight > copy_height ? copy_height : cheight;
-               size = (cheight * pitch) >> 2;
+               size = (cheight * pitch) / 4;
                /* emit reloc before writting cs so that cs is always in consistent state */
                r600_context_bo_reloc(&rctx->b, &rctx->b.rings.dma, &rsrc->resource, RADEON_USAGE_READ,
                                      RADEON_PRIO_MIN);
@@ -2930,11 +2930,11 @@ static void r600_dma_blit(struct pipe_context *ctx,
        dst_mode = dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED ? RADEON_SURF_MODE_LINEAR : dst_mode;
 
        if (src_pitch != dst_pitch || src_box->x || dst_x || src_w != dst_w) {
-               /* strick requirement on r6xx/r7xx */
+               /* strict requirement on r6xx/r7xx */
                goto fallback;
        }
        /* lot of constraint on alignment this should capture them all */
-       if ((src_pitch & 0x7) || (src_box->y & 0x7) || (dst_y & 0x7)) {
+       if (src_pitch % 8 || src_box->y % 8 || dst_y % 8) {
                goto fallback;
        }
 
@@ -2954,7 +2954,7 @@ static void r600_dma_blit(struct pipe_context *ctx,
                dst_offset += dst_y * dst_pitch + dst_x * bpp;
                size = src_box->height * src_pitch;
                /* must be dw aligned */
-               if ((dst_offset & 0x3) || (src_offset & 0x3) || (size & 0x3)) {
+               if (dst_offset % 4 || src_offset % 4 || size % 4) {
                        goto fallback;
                }
                r600_dma_copy(rctx, dst, src, dst_offset, src_offset, size);
index 05d1f0ab34ad6345d13f58ac2364f0cba065e98f..f787803a53e5df4724d09da30a6581ca45cb0702 100644 (file)
 /* async DMA Packet types */
 #define DMA_PACKET_WRITE               0x2
 #define DMA_PACKET_COPY                        0x3
+#define R600_DMA_COPY_MAX_SIZE_DW              0xffff
 #define DMA_PACKET_INDIRECT_BUFFER     0x4
 #define DMA_PACKET_SEMAPHORE           0x5
 #define DMA_PACKET_FENCE               0x6