1.buffer使用image的方式:Horizontal 与 Vertical 算法一样, 共需30ms,wait time 19ms.
const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST; __kernel void ImageGaussianFilterHorizontal(__read_only image2d_t source, // Source image __write_only image2d_t dest, // Intermediate dest image const int imgWidth , // Image width const int imgHeight) { const int y = get_global_id(0); if(y>=(imgHeight)) return; const float m_nFilter[11] = {1/256.0,4/256.0,8/256.0,16/256.0,32/256.0,134/256.0,32/256.0,16/256.0,8/256.0,4/256.0,1/256.0}; const int s = 11; const int nStart = 5; float lines[11]; for(int i=0;i<11;i++) lines[i] = read_imagef( source, sampler, (int2) (i-5, y) ).x; for(int j=0;j<imgWidth;){ float sum = lines[nStart] * m_nFilter[nStart]; #define GaussianTwoLines(m) \ sum += ( (lines[m] + lines[s-1-m])*m_nFilter[m] ); GaussianTwoLines(0) GaussianTwoLines(1) GaussianTwoLines(2) GaussianTwoLines(3) GaussianTwoLines(4) write_imagef( dest, (int2) (j, y), sum ); for(int i = 0; i<s-1; i++) lines[i] = lines[i+1]; j++; lines[s-1] = read_imagef( source, sampler, (int2) (j+5, y) ).x; } } __kernel void ImageGaussianFilterVertical(__read_only image2d_t source, // Source image __write_only image2d_t dest, const int imgWidth , const int imgHeight) { const int x = get_global_id(0); if(x>=(imgWidth)) return; const float m_nFilter[11] = {1/256.0,4/256.0,8/256.0,16/256.0,32/256.0,134/256.0,32/256.0,16/256.0,8/256.0,4/256.0,1/256.0}; const int s = 11; const int nStart = 5; float lines[11]; for(int i=0;i<11;i++) lines[i] = read_imagef( source, sampler, (int2) (x ,i-5) ).x; for(int j=0;j<imgHeight;){ float sum = lines[nStart] * m_nFilter[nStart]; #define GaussianTwoLines(m) \ sum += ( (lines[m] + lines[s-1-m])*m_nFilter[m] ); GaussianTwoLines(0) GaussianTwoLines(1) GaussianTwoLines(2) GaussianTwoLines(3) GaussianTwoLines(4) write_imagef( dest, (int2) (x, j), sum ); for(int i = 0; i<s-1; i++) lines[i] = lines[i+1]; j++; lines[s-1] = read_imagef( source, sampler, (int2) (x,j+5) ).x; } }