101e04c3fSmrg/*
201e04c3fSmrg * Copyright (c) 2012-2015 Etnaviv Project
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the
1201e04c3fSmrg * next paragraph) shall be included in all copies or substantial portions
1301e04c3fSmrg * of the Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2101e04c3fSmrg * DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg *
2301e04c3fSmrg * Authors:
2401e04c3fSmrg *    Wladimir J. van der Laan <laanwj@gmail.com>
2501e04c3fSmrg */
2601e04c3fSmrg
2701e04c3fSmrg#include "etnaviv_tiling.h"
2801e04c3fSmrg
2901e04c3fSmrg#include <stdint.h>
3001e04c3fSmrg#include <stdio.h>
3101e04c3fSmrg
3201e04c3fSmrg#define TEX_TILE_WIDTH (4)
3301e04c3fSmrg#define TEX_TILE_HEIGHT (4)
3401e04c3fSmrg#define TEX_TILE_WORDS (TEX_TILE_WIDTH * TEX_TILE_HEIGHT)
3501e04c3fSmrg
3601e04c3fSmrg#define DO_TILE(type)                                                   \
3701e04c3fSmrg   src_stride /= sizeof(type);                                          \
3801e04c3fSmrg   dst_stride = (dst_stride * TEX_TILE_HEIGHT) / sizeof(type);          \
3901e04c3fSmrg   for (unsigned srcy = 0; srcy < height; ++srcy) {                     \
4001e04c3fSmrg      unsigned dsty = basey + srcy;                                     \
4101e04c3fSmrg      unsigned ty = (dsty / TEX_TILE_HEIGHT) * dst_stride +             \
4201e04c3fSmrg                    (dsty % TEX_TILE_HEIGHT) * TEX_TILE_WIDTH;          \
4301e04c3fSmrg      for (unsigned srcx = 0; srcx < width; ++srcx) {                   \
4401e04c3fSmrg         unsigned dstx = basex + srcx;                                  \
4501e04c3fSmrg         ((type *)dest)[ty + (dstx / TEX_TILE_WIDTH) * TEX_TILE_WORDS + \
4601e04c3fSmrg                        (dstx % TEX_TILE_WIDTH)] =                      \
4701e04c3fSmrg            ((type *)src)[srcy * src_stride + srcx];                    \
4801e04c3fSmrg      }                                                                 \
4901e04c3fSmrg   }
5001e04c3fSmrg
5101e04c3fSmrg#define DO_UNTILE(type)                                                   \
5201e04c3fSmrg   src_stride = (src_stride * TEX_TILE_HEIGHT) / sizeof(type);            \
5301e04c3fSmrg   dst_stride /= sizeof(type);                                            \
5401e04c3fSmrg   for (unsigned dsty = 0; dsty < height; ++dsty) {                       \
5501e04c3fSmrg      unsigned srcy = basey + dsty;                                       \
5601e04c3fSmrg      unsigned sy = (srcy / TEX_TILE_HEIGHT) * src_stride +               \
5701e04c3fSmrg                    (srcy % TEX_TILE_HEIGHT) * TEX_TILE_WIDTH;            \
5801e04c3fSmrg      for (unsigned dstx = 0; dstx < width; ++dstx) {                     \
5901e04c3fSmrg         unsigned srcx = basex + dstx;                                    \
6001e04c3fSmrg         ((type *)dest)[dsty * dst_stride + dstx] =                       \
6101e04c3fSmrg            ((type *)src)[sy + (srcx / TEX_TILE_WIDTH) * TEX_TILE_WORDS + \
6201e04c3fSmrg                          (srcx % TEX_TILE_WIDTH)];                       \
6301e04c3fSmrg      }                                                                   \
6401e04c3fSmrg   }
6501e04c3fSmrg
6601e04c3fSmrgvoid
6701e04c3fSmrgetna_texture_tile(void *dest, void *src, unsigned basex, unsigned basey,
6801e04c3fSmrg                  unsigned dst_stride, unsigned width, unsigned height,
6901e04c3fSmrg                  unsigned src_stride, unsigned elmtsize)
7001e04c3fSmrg{
717ec681f3Smrg   if (elmtsize == 8) {
727ec681f3Smrg      DO_TILE(uint64_t)
737ec681f3Smrg   } else if (elmtsize == 4) {
7401e04c3fSmrg      DO_TILE(uint32_t)
7501e04c3fSmrg   } else if (elmtsize == 2) {
7601e04c3fSmrg      DO_TILE(uint16_t)
7701e04c3fSmrg   } else if (elmtsize == 1) {
7801e04c3fSmrg      DO_TILE(uint8_t)
7901e04c3fSmrg   } else {
8001e04c3fSmrg      printf("etna_texture_tile: unhandled element size %i\n", elmtsize);
8101e04c3fSmrg   }
8201e04c3fSmrg}
8301e04c3fSmrg
8401e04c3fSmrgvoid
8501e04c3fSmrgetna_texture_untile(void *dest, void *src, unsigned basex, unsigned basey,
8601e04c3fSmrg                    unsigned src_stride, unsigned width, unsigned height,
8701e04c3fSmrg                    unsigned dst_stride, unsigned elmtsize)
8801e04c3fSmrg{
897ec681f3Smrg   if (elmtsize == 8) {
907ec681f3Smrg      DO_UNTILE(uint64_t)
917ec681f3Smrg   } else if (elmtsize == 4) {
9201e04c3fSmrg      DO_UNTILE(uint32_t);
9301e04c3fSmrg   } else if (elmtsize == 2) {
9401e04c3fSmrg      DO_UNTILE(uint16_t);
9501e04c3fSmrg   } else if (elmtsize == 1) {
9601e04c3fSmrg      DO_UNTILE(uint8_t);
9701e04c3fSmrg   } else {
9801e04c3fSmrg      printf("etna_texture_tile: unhandled element size %i\n", elmtsize);
9901e04c3fSmrg   }
10001e04c3fSmrg}
101