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