// // Copyright (c) 2014-2015 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // #include "common/mathutil.h" namespace rx { template inline T *OffsetDataPointer(uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch) { return reinterpret_cast(data + (y * rowPitch) + (z * depthPitch)); } template inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch) { return reinterpret_cast(data + (y * rowPitch) + (z * depthPitch)); } template inline void LoadToNative(size_t width, size_t height, size_t depth, const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { const size_t rowSize = width * sizeof(type) * componentCount; const size_t layerSize = rowSize * height; const size_t imageSize = layerSize * depth; if (layerSize == inputDepthPitch && layerSize == outputDepthPitch) { ASSERT(rowSize == inputRowPitch && rowSize == outputRowPitch); memcpy(output, input, imageSize); } else if (rowSize == inputRowPitch && rowSize == outputRowPitch) { for (size_t z = 0; z < depth; z++) { const type *source = OffsetDataPointer(input, 0, z, inputRowPitch, inputDepthPitch); type *dest = OffsetDataPointer(output, 0, z, outputRowPitch, outputDepthPitch); memcpy(dest, source, layerSize); } } else { for (size_t z = 0; z < depth; z++) { for (size_t y = 0; y < height; y++) { const type *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); type *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); memcpy(dest, source, width * sizeof(type) * componentCount); } } } } template inline void LoadToNative3To4(size_t width, size_t height, size_t depth, const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { const type fourthValue = gl::bitCast(fourthComponentBits); for (size_t z = 0; z < depth; z++) { for (size_t y = 0; y < height; y++) { const type *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); type *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x++) { dest[x * 4 + 0] = source[x * 3 + 0]; dest[x * 4 + 1] = source[x * 3 + 1]; dest[x * 4 + 2] = source[x * 3 + 2]; dest[x * 4 + 3] = fourthValue; } } } } template inline void Load32FTo16F(size_t width, size_t height, size_t depth, const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { const size_t elementWidth = componentCount * width; for (size_t z = 0; z < depth; z++) { for (size_t y = 0; y < height; y++) { const float *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); uint16_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < elementWidth; x++) { dest[x] = gl::float32ToFloat16(source[x]); } } } } template inline void LoadCompressedToNative(size_t width, size_t height, size_t depth, const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { const size_t columns = (width + (blockWidth - 1)) / blockWidth; const size_t rows = (height + (blockHeight - 1)) / blockHeight; for (size_t z = 0; z < depth; ++z) { for (size_t y = 0; y < rows; ++y) { const uint8_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); memcpy(dest, source, columns * blockSize); } } } template inline void Initialize4ComponentData(size_t width, size_t height, size_t depth, uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { type writeValues[4] = { gl::bitCast(firstBits), gl::bitCast(secondBits), gl::bitCast(thirdBits), gl::bitCast(fourthBits), }; for (size_t z = 0; z < depth; z++) { for (size_t y = 0; y < height; y++) { type *destRow = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x++) { type* destPixel = destRow + x * 4; // This could potentially be optimized by generating an entire row of initialization // data and copying row by row instead of pixel by pixel. memcpy(destPixel, writeValues, sizeof(type) * 4); } } } } }