Home | History | Annotate | Download | only in renderer
      1 //
      2 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 #include "common/mathutil.h"
      8 
      9 namespace rx
     10 {
     11 
     12 template <typename T>
     13 inline T *OffsetDataPointer(uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch)
     14 {
     15     return reinterpret_cast<T*>(data + (y * rowPitch) + (z * depthPitch));
     16 }
     17 
     18 template <typename T>
     19 inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch)
     20 {
     21     return reinterpret_cast<const T*>(data + (y * rowPitch) + (z * depthPitch));
     22 }
     23 
     24 template <typename type, size_t componentCount>
     25 inline void LoadToNative(size_t width, size_t height, size_t depth,
     26                          const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
     27                          uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
     28 {
     29     const size_t rowSize = width * sizeof(type) * componentCount;
     30     const size_t layerSize = rowSize * height;
     31     const size_t imageSize = layerSize * depth;
     32 
     33     if (layerSize == inputDepthPitch && layerSize == outputDepthPitch)
     34     {
     35         ASSERT(rowSize == inputRowPitch && rowSize == outputRowPitch);
     36         memcpy(output, input, imageSize);
     37     }
     38     else if (rowSize == inputRowPitch && rowSize == outputRowPitch)
     39     {
     40         for (size_t z = 0; z < depth; z++)
     41         {
     42             const type *source = OffsetDataPointer<type>(input, 0, z, inputRowPitch, inputDepthPitch);
     43             type *dest = OffsetDataPointer<type>(output, 0, z, outputRowPitch, outputDepthPitch);
     44 
     45             memcpy(dest, source, layerSize);
     46         }
     47     }
     48     else
     49     {
     50         for (size_t z = 0; z < depth; z++)
     51         {
     52             for (size_t y = 0; y < height; y++)
     53             {
     54                 const type *source = OffsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch);
     55                 type *dest = OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch);
     56                 memcpy(dest, source, width * sizeof(type) * componentCount);
     57             }
     58         }
     59     }
     60 }
     61 
     62 template <typename type, uint32_t fourthComponentBits>
     63 inline void LoadToNative3To4(size_t width, size_t height, size_t depth,
     64                              const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
     65                              uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
     66 {
     67     const type fourthValue = gl::bitCast<type>(fourthComponentBits);
     68 
     69     for (size_t z = 0; z < depth; z++)
     70     {
     71         for (size_t y = 0; y < height; y++)
     72         {
     73             const type *source = OffsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch);
     74             type *dest = OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch);
     75             for (size_t x = 0; x < width; x++)
     76             {
     77                 dest[x * 4 + 0] = source[x * 3 + 0];
     78                 dest[x * 4 + 1] = source[x * 3 + 1];
     79                 dest[x * 4 + 2] = source[x * 3 + 2];
     80                 dest[x * 4 + 3] = fourthValue;
     81             }
     82         }
     83     }
     84 }
     85 
     86 template <size_t componentCount>
     87 inline void Load32FTo16F(size_t width, size_t height, size_t depth,
     88                          const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
     89                          uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
     90 {
     91     const size_t elementWidth = componentCount * width;
     92 
     93     for (size_t z = 0; z < depth; z++)
     94     {
     95         for (size_t y = 0; y < height; y++)
     96         {
     97             const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
     98             uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
     99 
    100             for (size_t x = 0; x < elementWidth; x++)
    101             {
    102                 dest[x] = gl::float32ToFloat16(source[x]);
    103             }
    104         }
    105     }
    106 }
    107 
    108 template <size_t blockWidth, size_t blockHeight, size_t blockSize>
    109 inline void LoadCompressedToNative(size_t width, size_t height, size_t depth,
    110                                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    111                                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    112 {
    113     const size_t columns = (width + (blockWidth - 1)) / blockWidth;
    114     const size_t rows = (height + (blockHeight - 1)) / blockHeight;
    115 
    116     for (size_t z = 0; z < depth; ++z)
    117     {
    118         for (size_t y = 0; y < rows; ++y)
    119         {
    120             const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
    121             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    122             memcpy(dest, source, columns * blockSize);
    123         }
    124     }
    125 }
    126 
    127 template <typename type, uint32_t firstBits, uint32_t secondBits, uint32_t thirdBits, uint32_t fourthBits>
    128 inline void Initialize4ComponentData(size_t width, size_t height, size_t depth,
    129                                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    130 {
    131     type writeValues[4] =
    132     {
    133         gl::bitCast<type>(firstBits),
    134         gl::bitCast<type>(secondBits),
    135         gl::bitCast<type>(thirdBits),
    136         gl::bitCast<type>(fourthBits),
    137     };
    138 
    139     for (size_t z = 0; z < depth; z++)
    140     {
    141         for (size_t y = 0; y < height; y++)
    142         {
    143             type *destRow = OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch);
    144             for (size_t x = 0; x < width; x++)
    145             {
    146                 type* destPixel = destRow + x * 4;
    147 
    148                 // This could potentially be optimized by generating an entire row of initialization
    149                 // data and copying row by row instead of pixel by pixel.
    150                 memcpy(destPixel, writeValues, sizeof(type) * 4);
    151             }
    152         }
    153     }
    154 }
    155 
    156 }
    157