1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/libGLESv2/renderer/generatemip.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,203 @@ 1.4 +// 1.5 +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. 1.6 +// Use of this source code is governed by a BSD-style license that can be 1.7 +// found in the LICENSE file. 1.8 +// 1.9 + 1.10 +// generatemip.h: Defines the GenerateMip function, templated on the format 1.11 +// type of the image for which mip levels are being generated. 1.12 + 1.13 +#ifndef LIBGLESV2_RENDERER_GENERATEMIP_H_ 1.14 +#define LIBGLESV2_RENDERER_GENERATEMIP_H_ 1.15 + 1.16 +#include "libGLESv2/mathutil.h" 1.17 + 1.18 +namespace rx 1.19 +{ 1.20 +struct L8 1.21 +{ 1.22 + unsigned char L; 1.23 + 1.24 + static void average(L8 *dst, const L8 *src1, const L8 *src2) 1.25 + { 1.26 + dst->L = ((src1->L ^ src2->L) >> 1) + (src1->L & src2->L); 1.27 + } 1.28 +}; 1.29 + 1.30 +typedef L8 R8; // R8 type is functionally equivalent for mip purposes 1.31 +typedef L8 A8; // A8 type is functionally equivalent for mip purposes 1.32 + 1.33 +struct A8L8 1.34 +{ 1.35 + unsigned char L; 1.36 + unsigned char A; 1.37 + 1.38 + static void average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2) 1.39 + { 1.40 + *(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2); 1.41 + } 1.42 +}; 1.43 + 1.44 +typedef A8L8 R8G8; // R8G8 type is functionally equivalent for mip purposes 1.45 + 1.46 +struct A8R8G8B8 1.47 +{ 1.48 + unsigned char B; 1.49 + unsigned char G; 1.50 + unsigned char R; 1.51 + unsigned char A; 1.52 + 1.53 + static void average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2) 1.54 + { 1.55 + *(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); 1.56 + } 1.57 +}; 1.58 + 1.59 +typedef A8R8G8B8 R8G8B8A8; // R8G8B8A8 type is functionally equivalent for mip purposes 1.60 + 1.61 +struct A16B16G16R16F 1.62 +{ 1.63 + unsigned short R; 1.64 + unsigned short G; 1.65 + unsigned short B; 1.66 + unsigned short A; 1.67 + 1.68 + static void average(A16B16G16R16F *dst, const A16B16G16R16F *src1, const A16B16G16R16F *src2) 1.69 + { 1.70 + dst->R = gl::float32ToFloat16((gl::float16ToFloat32(src1->R) + gl::float16ToFloat32(src2->R)) * 0.5f); 1.71 + dst->G = gl::float32ToFloat16((gl::float16ToFloat32(src1->G) + gl::float16ToFloat32(src2->G)) * 0.5f); 1.72 + dst->B = gl::float32ToFloat16((gl::float16ToFloat32(src1->B) + gl::float16ToFloat32(src2->B)) * 0.5f); 1.73 + dst->A = gl::float32ToFloat16((gl::float16ToFloat32(src1->A) + gl::float16ToFloat32(src2->A)) * 0.5f); 1.74 + } 1.75 +}; 1.76 + 1.77 +struct R16F 1.78 +{ 1.79 + unsigned short R; 1.80 + 1.81 + static void average(R16F *dst, const R16F *src1, const R16F *src2) 1.82 + { 1.83 + dst->R = gl::float32ToFloat16((gl::float16ToFloat32(src1->R) + gl::float16ToFloat32(src2->R)) * 0.5f); 1.84 + } 1.85 +}; 1.86 + 1.87 +struct R16G16F 1.88 +{ 1.89 + unsigned short R; 1.90 + unsigned short G; 1.91 + 1.92 + static void average(R16G16F *dst, const R16G16F *src1, const R16G16F *src2) 1.93 + { 1.94 + dst->R = gl::float32ToFloat16((gl::float16ToFloat32(src1->R) + gl::float16ToFloat32(src2->R)) * 0.5f); 1.95 + dst->G = gl::float32ToFloat16((gl::float16ToFloat32(src1->G) + gl::float16ToFloat32(src2->G)) * 0.5f); 1.96 + } 1.97 +}; 1.98 + 1.99 +struct A32B32G32R32F 1.100 +{ 1.101 + float R; 1.102 + float G; 1.103 + float B; 1.104 + float A; 1.105 + 1.106 + static void average(A32B32G32R32F *dst, const A32B32G32R32F *src1, const A32B32G32R32F *src2) 1.107 + { 1.108 + dst->R = (src1->R + src2->R) * 0.5f; 1.109 + dst->G = (src1->G + src2->G) * 0.5f; 1.110 + dst->B = (src1->B + src2->B) * 0.5f; 1.111 + dst->A = (src1->A + src2->A) * 0.5f; 1.112 + } 1.113 +}; 1.114 + 1.115 +struct R32F 1.116 +{ 1.117 + float R; 1.118 + 1.119 + static void average(R32F *dst, const R32F *src1, const R32F *src2) 1.120 + { 1.121 + dst->R = (src1->R + src2->R) * 0.5f; 1.122 + } 1.123 +}; 1.124 + 1.125 +struct R32G32F 1.126 +{ 1.127 + float R; 1.128 + float G; 1.129 + 1.130 + static void average(R32G32F *dst, const R32G32F *src1, const R32G32F *src2) 1.131 + { 1.132 + dst->R = (src1->R + src2->R) * 0.5f; 1.133 + dst->G = (src1->G + src2->G) * 0.5f; 1.134 + } 1.135 +}; 1.136 + 1.137 +struct R32G32B32F 1.138 +{ 1.139 + float R; 1.140 + float G; 1.141 + float B; 1.142 + 1.143 + static void average(R32G32B32F *dst, const R32G32B32F *src1, const R32G32B32F *src2) 1.144 + { 1.145 + dst->R = (src1->R + src2->R) * 0.5f; 1.146 + dst->G = (src1->G + src2->G) * 0.5f; 1.147 + dst->B = (src1->B + src2->B) * 0.5f; 1.148 + } 1.149 +}; 1.150 + 1.151 +template <typename T> 1.152 +static void GenerateMip(unsigned int sourceWidth, unsigned int sourceHeight, 1.153 + const unsigned char *sourceData, int sourcePitch, 1.154 + unsigned char *destData, int destPitch) 1.155 +{ 1.156 + unsigned int mipWidth = std::max(1U, sourceWidth >> 1); 1.157 + unsigned int mipHeight = std::max(1U, sourceHeight >> 1); 1.158 + 1.159 + if (sourceHeight == 1) 1.160 + { 1.161 + ASSERT(sourceWidth != 1); 1.162 + 1.163 + const T *src = (const T*)sourceData; 1.164 + T *dst = (T*)destData; 1.165 + 1.166 + for (unsigned int x = 0; x < mipWidth; x++) 1.167 + { 1.168 + T::average(&dst[x], &src[x * 2], &src[x * 2 + 1]); 1.169 + } 1.170 + } 1.171 + else if (sourceWidth == 1) 1.172 + { 1.173 + ASSERT(sourceHeight != 1); 1.174 + 1.175 + for (unsigned int y = 0; y < mipHeight; y++) 1.176 + { 1.177 + const T *src0 = (const T*)(sourceData + y * 2 * sourcePitch); 1.178 + const T *src1 = (const T*)(sourceData + y * 2 * sourcePitch + sourcePitch); 1.179 + T *dst = (T*)(destData + y * destPitch); 1.180 + 1.181 + T::average(dst, src0, src1); 1.182 + } 1.183 + } 1.184 + else 1.185 + { 1.186 + for (unsigned int y = 0; y < mipHeight; y++) 1.187 + { 1.188 + const T *src0 = (const T*)(sourceData + y * 2 * sourcePitch); 1.189 + const T *src1 = (const T*)(sourceData + y * 2 * sourcePitch + sourcePitch); 1.190 + T *dst = (T*)(destData + y * destPitch); 1.191 + 1.192 + for (unsigned int x = 0; x < mipWidth; x++) 1.193 + { 1.194 + T tmp0; 1.195 + T tmp1; 1.196 + 1.197 + T::average(&tmp0, &src0[x * 2], &src0[x * 2 + 1]); 1.198 + T::average(&tmp1, &src1[x * 2], &src1[x * 2 + 1]); 1.199 + T::average(&dst[x], &tmp0, &tmp1); 1.200 + } 1.201 + } 1.202 + } 1.203 +} 1.204 +} 1.205 + 1.206 +#endif // LIBGLESV2_RENDERER_GENERATEMIP_H_