Apply consistent code formatting across the repo. Add clang-format and pre-commit hooks.

This commit is contained in:
Rob Armstrong
2025-03-27 10:30:07 -07:00
parent 2cd58fbc9a
commit ceab6e8bcc
782 changed files with 107230 additions and 106548 deletions

View File

@@ -34,4 +34,3 @@ Download and install the [CUDA Toolkit 12.5](https://developer.nvidia.com/cuda-d
Make sure the dependencies mentioned in [Dependencies]() section above are installed.
## References (for more details)

File diff suppressed because it is too large Load Diff

View File

@@ -28,101 +28,107 @@
#ifndef _BICUBICTEXTURE_CU_
#define _BICUBICTEXTURE_CU_
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <helper_math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// includes, cuda
#include <helper_cuda.h>
typedef unsigned int uint;
typedef unsigned int uint;
typedef unsigned char uchar;
#include "bicubicTexture_kernel.cuh"
cudaArray *d_imageArray = 0;
extern "C" void initTexture(int imageWidth, int imageHeight, uchar *h_data) {
// allocate array and copy image data
cudaChannelFormatDesc channelDesc =
cudaCreateChannelDesc(8, 0, 0, 0, cudaChannelFormatKindUnsigned);
checkCudaErrors(
cudaMallocArray(&d_imageArray, &channelDesc, imageWidth, imageHeight));
checkCudaErrors(cudaMemcpy2DToArray(
d_imageArray, 0, 0, h_data, imageWidth * sizeof(uchar),
imageWidth * sizeof(uchar), imageHeight, cudaMemcpyHostToDevice));
free(h_data);
extern "C" void initTexture(int imageWidth, int imageHeight, uchar *h_data)
{
// allocate array and copy image data
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(8, 0, 0, 0, cudaChannelFormatKindUnsigned);
checkCudaErrors(cudaMallocArray(&d_imageArray, &channelDesc, imageWidth, imageHeight));
checkCudaErrors(cudaMemcpy2DToArray(d_imageArray,
0,
0,
h_data,
imageWidth * sizeof(uchar),
imageWidth * sizeof(uchar),
imageHeight,
cudaMemcpyHostToDevice));
free(h_data);
cudaResourceDesc texRes;
memset(&texRes, 0, sizeof(cudaResourceDesc));
cudaResourceDesc texRes;
memset(&texRes, 0, sizeof(cudaResourceDesc));
texRes.resType = cudaResourceTypeArray;
texRes.res.array.array = d_imageArray;
texRes.resType = cudaResourceTypeArray;
texRes.res.array.array = d_imageArray;
cudaTextureDesc texDescr;
memset(&texDescr, 0, sizeof(cudaTextureDesc));
cudaTextureDesc texDescr;
memset(&texDescr, 0, sizeof(cudaTextureDesc));
texDescr.normalizedCoords = false;
texDescr.filterMode = cudaFilterModeLinear;
texDescr.addressMode[0] = cudaAddressModeClamp;
texDescr.addressMode[1] = cudaAddressModeClamp;
texDescr.readMode = cudaReadModeNormalizedFloat;
texDescr.normalizedCoords = false;
texDescr.filterMode = cudaFilterModeLinear;
texDescr.addressMode[0] = cudaAddressModeClamp;
texDescr.addressMode[1] = cudaAddressModeClamp;
texDescr.readMode = cudaReadModeNormalizedFloat;
checkCudaErrors(
cudaCreateTextureObject(&texObjLinear, &texRes, &texDescr, NULL));
checkCudaErrors(cudaCreateTextureObject(&texObjLinear, &texRes, &texDescr, NULL));
memset(&texDescr, 0, sizeof(cudaTextureDesc));
texDescr.normalizedCoords = false;
texDescr.filterMode = cudaFilterModePoint;
texDescr.addressMode[0] = cudaAddressModeClamp;
texDescr.addressMode[1] = cudaAddressModeClamp;
texDescr.readMode = cudaReadModeNormalizedFloat;
memset(&texDescr, 0, sizeof(cudaTextureDesc));
texDescr.normalizedCoords = false;
texDescr.filterMode = cudaFilterModePoint;
texDescr.addressMode[0] = cudaAddressModeClamp;
texDescr.addressMode[1] = cudaAddressModeClamp;
texDescr.readMode = cudaReadModeNormalizedFloat;
checkCudaErrors(
cudaCreateTextureObject(&texObjPoint, &texRes, &texDescr, NULL));
checkCudaErrors(cudaCreateTextureObject(&texObjPoint, &texRes, &texDescr, NULL));
}
extern "C" void freeTexture() {
checkCudaErrors(cudaDestroyTextureObject(texObjPoint));
checkCudaErrors(cudaDestroyTextureObject(texObjLinear));
checkCudaErrors(cudaFreeArray(d_imageArray));
extern "C" void freeTexture()
{
checkCudaErrors(cudaDestroyTextureObject(texObjPoint));
checkCudaErrors(cudaDestroyTextureObject(texObjLinear));
checkCudaErrors(cudaFreeArray(d_imageArray));
}
// render image using CUDA
extern "C" void render(int width, int height, float tx, float ty, float scale,
float cx, float cy, dim3 blockSize, dim3 gridSize,
int filter_mode, uchar4 *output) {
// call CUDA kernel, writing results to PBO memory
switch (filter_mode) {
extern "C" void render(int width,
int height,
float tx,
float ty,
float scale,
float cx,
float cy,
dim3 blockSize,
dim3 gridSize,
int filter_mode,
uchar4 *output)
{
// call CUDA kernel, writing results to PBO memory
switch (filter_mode) {
case MODE_NEAREST:
d_render<<<gridSize, blockSize>>>(output, width, height, tx, ty, scale,
cx, cy, texObjPoint);
break;
d_render<<<gridSize, blockSize>>>(output, width, height, tx, ty, scale, cx, cy, texObjPoint);
break;
case MODE_BILINEAR:
d_render<<<gridSize, blockSize>>>(output, width, height, tx, ty, scale,
cx, cy, texObjLinear);
break;
d_render<<<gridSize, blockSize>>>(output, width, height, tx, ty, scale, cx, cy, texObjLinear);
break;
case MODE_BICUBIC:
d_renderBicubic<<<gridSize, blockSize>>>(output, width, height, tx, ty,
scale, cx, cy, texObjPoint);
break;
d_renderBicubic<<<gridSize, blockSize>>>(output, width, height, tx, ty, scale, cx, cy, texObjPoint);
break;
case MODE_FAST_BICUBIC:
d_renderFastBicubic<<<gridSize, blockSize>>>(
output, width, height, tx, ty, scale, cx, cy, texObjLinear);
break;
d_renderFastBicubic<<<gridSize, blockSize>>>(output, width, height, tx, ty, scale, cx, cy, texObjLinear);
break;
case MODE_CATROM:
d_renderCatRom<<<gridSize, blockSize>>>(output, width, height, tx, ty,
scale, cx, cy, texObjPoint);
break;
}
d_renderCatRom<<<gridSize, blockSize>>>(output, width, height, tx, ty, scale, cx, cy, texObjPoint);
break;
}
getLastCudaError("kernel failed");
getLastCudaError("kernel failed");
}
#endif

View File

@@ -36,30 +36,27 @@
#ifndef _BICUBICTEXTURE_KERNEL_CUH_
#define _BICUBICTEXTURE_KERNEL_CUH_
enum Mode {
MODE_NEAREST,
MODE_BILINEAR,
MODE_BICUBIC,
MODE_FAST_BICUBIC,
MODE_CATROM
};
enum Mode { MODE_NEAREST, MODE_BILINEAR, MODE_BICUBIC, MODE_FAST_BICUBIC, MODE_CATROM };
cudaTextureObject_t texObjPoint, texObjLinear;
// w0, w1, w2, and w3 are the four cubic B-spline basis functions
__host__ __device__ float w0(float a) {
// return (1.0f/6.0f)*(-a*a*a + 3.0f*a*a - 3.0f*a + 1.0f);
return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f); // optimized
__host__ __device__ float w0(float a)
{
// return (1.0f/6.0f)*(-a*a*a + 3.0f*a*a - 3.0f*a + 1.0f);
return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f); // optimized
}
__host__ __device__ float w1(float a) {
// return (1.0f/6.0f)*(3.0f*a*a*a - 6.0f*a*a + 4.0f);
return (1.0f / 6.0f) * (a * a * (3.0f * a - 6.0f) + 4.0f);
__host__ __device__ float w1(float a)
{
// return (1.0f/6.0f)*(3.0f*a*a*a - 6.0f*a*a + 4.0f);
return (1.0f / 6.0f) * (a * a * (3.0f * a - 6.0f) + 4.0f);
}
__host__ __device__ float w2(float a) {
// return (1.0f/6.0f)*(-3.0f*a*a*a + 3.0f*a*a + 3.0f*a + 1.0f);
return (1.0f / 6.0f) * (a * (a * (-3.0f * a + 3.0f) + 3.0f) + 1.0f);
__host__ __device__ float w2(float a)
{
// return (1.0f/6.0f)*(-3.0f*a*a*a + 3.0f*a*a + 3.0f*a + 1.0f);
return (1.0f / 6.0f) * (a * (a * (-3.0f * a + 3.0f) + 3.0f) + 1.0f);
}
__host__ __device__ float w3(float a) { return (1.0f / 6.0f) * (a * a * a); }
@@ -70,91 +67,99 @@ __device__ float g0(float a) { return w0(a) + w1(a); }
__device__ float g1(float a) { return w2(a) + w3(a); }
// h0 and h1 are the two offset functions
__device__ float h0(float a) {
// note +0.5 offset to compensate for CUDA linear filtering convention
return -1.0f + w1(a) / (w0(a) + w1(a)) + 0.5f;
__device__ float h0(float a)
{
// note +0.5 offset to compensate for CUDA linear filtering convention
return -1.0f + w1(a) / (w0(a) + w1(a)) + 0.5f;
}
__device__ float h1(float a) { return 1.0f + w3(a) / (w2(a) + w3(a)) + 0.5f; }
// filter 4 values using cubic splines
template <class T>
__device__ T cubicFilter(float x, T c0, T c1, T c2, T c3) {
T r;
r = c0 * w0(x);
r += c1 * w1(x);
r += c2 * w2(x);
r += c3 * w3(x);
return r;
template <class T> __device__ T cubicFilter(float x, T c0, T c1, T c2, T c3)
{
T r;
r = c0 * w0(x);
r += c1 * w1(x);
r += c2 * w2(x);
r += c3 * w3(x);
return r;
}
// slow but precise bicubic lookup using 16 texture lookups
template <class T, class R> // texture data type, return type
__device__ R tex2DBicubic(const cudaTextureObject_t tex, float x, float y) {
x -= 0.5f;
y -= 0.5f;
float px = floorf(x);
float py = floorf(y);
float fx = x - px;
float fy = y - py;
template <class T, class R> // texture data type, return type
__device__ R tex2DBicubic(const cudaTextureObject_t tex, float x, float y)
{
x -= 0.5f;
y -= 0.5f;
float px = floorf(x);
float py = floorf(y);
float fx = x - px;
float fy = y - py;
return cubicFilter<R>(
fy, cubicFilter<R>(
fx, tex2D<R>(tex, px - 1, py - 1), tex2D<R>(tex, px, py - 1),
tex2D<R>(tex, px + 1, py - 1), tex2D<R>(tex, px + 2, py - 1)),
cubicFilter<R>(fx, tex2D<R>(tex, px - 1, py), tex2D<R>(tex, px, py),
tex2D<R>(tex, px + 1, py), tex2D<R>(tex, px + 2, py)),
cubicFilter<R>(fx, tex2D<R>(tex, px - 1, py + 1),
tex2D<R>(tex, px, py + 1), tex2D<R>(tex, px + 1, py + 1),
tex2D<R>(tex, px + 2, py + 1)),
cubicFilter<R>(fx, tex2D<R>(tex, px - 1, py + 2),
tex2D<R>(tex, px, py + 2), tex2D<R>(tex, px + 1, py + 2),
tex2D<R>(tex, px + 2, py + 2)));
return cubicFilter<R>(
fy,
cubicFilter<R>(fx,
tex2D<R>(tex, px - 1, py - 1),
tex2D<R>(tex, px, py - 1),
tex2D<R>(tex, px + 1, py - 1),
tex2D<R>(tex, px + 2, py - 1)),
cubicFilter<R>(
fx, tex2D<R>(tex, px - 1, py), tex2D<R>(tex, px, py), tex2D<R>(tex, px + 1, py), tex2D<R>(tex, px + 2, py)),
cubicFilter<R>(fx,
tex2D<R>(tex, px - 1, py + 1),
tex2D<R>(tex, px, py + 1),
tex2D<R>(tex, px + 1, py + 1),
tex2D<R>(tex, px + 2, py + 1)),
cubicFilter<R>(fx,
tex2D<R>(tex, px - 1, py + 2),
tex2D<R>(tex, px, py + 2),
tex2D<R>(tex, px + 1, py + 2),
tex2D<R>(tex, px + 2, py + 2)));
}
// fast bicubic texture lookup using 4 bilinear lookups
// assumes texture is set to non-normalized coordinates, point sampling
template <class T, class R> // texture data type, return type
__device__ R tex2DFastBicubic(const cudaTextureObject_t tex, float x, float y) {
x -= 0.5f;
y -= 0.5f;
float px = floorf(x);
float py = floorf(y);
float fx = x - px;
float fy = y - py;
template <class T, class R> // texture data type, return type
__device__ R tex2DFastBicubic(const cudaTextureObject_t tex, float x, float y)
{
x -= 0.5f;
y -= 0.5f;
float px = floorf(x);
float py = floorf(y);
float fx = x - px;
float fy = y - py;
// note: we could store these functions in a lookup table texture, but maths
// is cheap
float g0x = g0(fx);
float g1x = g1(fx);
float h0x = h0(fx);
float h1x = h1(fx);
float h0y = h0(fy);
float h1y = h1(fy);
// note: we could store these functions in a lookup table texture, but maths
// is cheap
float g0x = g0(fx);
float g1x = g1(fx);
float h0x = h0(fx);
float h1x = h1(fx);
float h0y = h0(fy);
float h1y = h1(fy);
R r = g0(fy) * (g0x * tex2D<R>(tex, px + h0x, py + h0y) +
g1x * tex2D<R>(tex, px + h1x, py + h0y)) +
g1(fy) * (g0x * tex2D<R>(tex, px + h0x, py + h1y) +
g1x * tex2D<R>(tex, px + h1x, py + h1y));
return r;
R r = g0(fy) * (g0x * tex2D<R>(tex, px + h0x, py + h0y) + g1x * tex2D<R>(tex, px + h1x, py + h0y))
+ g1(fy) * (g0x * tex2D<R>(tex, px + h0x, py + h1y) + g1x * tex2D<R>(tex, px + h1x, py + h1y));
return r;
}
// higher-precision 2D bilinear lookup
template <class T, class R> // texture data type, return type
__device__ R tex2DBilinear(const cudaTextureObject_t tex, float x, float y) {
x -= 0.5f;
y -= 0.5f;
float px = floorf(x); // integer position
float py = floorf(y);
float fx = x - px; // fractional position
float fy = y - py;
px += 0.5f;
py += 0.5f;
template <class T, class R> // texture data type, return type
__device__ R tex2DBilinear(const cudaTextureObject_t tex, float x, float y)
{
x -= 0.5f;
y -= 0.5f;
float px = floorf(x); // integer position
float py = floorf(y);
float fx = x - px; // fractional position
float fy = y - py;
px += 0.5f;
py += 0.5f;
return lerp(lerp(tex2D<R>(tex, px, py), tex2D<R>(tex, px + 1.0f, py), fx),
lerp(tex2D<R>(tex, px, py + 1.0f),
tex2D<R>(tex, px + 1.0f, py + 1.0f), fx),
fy);
return lerp(lerp(tex2D<R>(tex, px, py), tex2D<R>(tex, px + 1.0f, py), fx),
lerp(tex2D<R>(tex, px, py + 1.0f), tex2D<R>(tex, px + 1.0f, py + 1.0f), fx),
fy);
}
#if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 200
@@ -174,154 +179,193 @@ __device__ R tex2DBilinear(const cudaTextureObject_t tex, float x, float y) {
w: (0, 0)
*/
template <class T, class R> // texture data type, return type
__device__ float tex2DBilinearGather(const cudaTextureObject_t tex, float x,
float y, int comp = 0) {
x -= 0.5f;
y -= 0.5f;
float px = floorf(x); // integer position
float py = floorf(y);
float fx = x - px; // fractional position
float fy = y - py;
template <class T, class R> // texture data type, return type
__device__ float tex2DBilinearGather(const cudaTextureObject_t tex, float x, float y, int comp = 0)
{
x -= 0.5f;
y -= 0.5f;
float px = floorf(x); // integer position
float py = floorf(y);
float fx = x - px; // fractional position
float fy = y - py;
R samples = tex2Dgather<R>(tex, px + 0.5f, py + 0.5f, comp);
R samples = tex2Dgather<R>(tex, px + 0.5f, py + 0.5f, comp);
return lerp(lerp((float)samples.w, (float)samples.z, fx),
lerp((float)samples.x, (float)samples.y, fx), fy);
return lerp(lerp((float)samples.w, (float)samples.z, fx), lerp((float)samples.x, (float)samples.y, fx), fy);
}
#endif
// Catmull-Rom interpolation
__host__ __device__ float catrom_w0(float a) {
// return -0.5f*a + a*a - 0.5f*a*a*a;
return a * (-0.5f + a * (1.0f - 0.5f * a));
__host__ __device__ float catrom_w0(float a)
{
// return -0.5f*a + a*a - 0.5f*a*a*a;
return a * (-0.5f + a * (1.0f - 0.5f * a));
}
__host__ __device__ float catrom_w1(float a) {
// return 1.0f - 2.5f*a*a + 1.5f*a*a*a;
return 1.0f + a * a * (-2.5f + 1.5f * a);
__host__ __device__ float catrom_w1(float a)
{
// return 1.0f - 2.5f*a*a + 1.5f*a*a*a;
return 1.0f + a * a * (-2.5f + 1.5f * a);
}
__host__ __device__ float catrom_w2(float a) {
// return 0.5f*a + 2.0f*a*a - 1.5f*a*a*a;
return a * (0.5f + a * (2.0f - 1.5f * a));
__host__ __device__ float catrom_w2(float a)
{
// return 0.5f*a + 2.0f*a*a - 1.5f*a*a*a;
return a * (0.5f + a * (2.0f - 1.5f * a));
}
__host__ __device__ float catrom_w3(float a) {
// return -0.5f*a*a + 0.5f*a*a*a;
return a * a * (-0.5f + 0.5f * a);
__host__ __device__ float catrom_w3(float a)
{
// return -0.5f*a*a + 0.5f*a*a*a;
return a * a * (-0.5f + 0.5f * a);
}
template <class T>
__device__ T catRomFilter(float x, T c0, T c1, T c2, T c3) {
T r;
r = c0 * catrom_w0(x);
r += c1 * catrom_w1(x);
r += c2 * catrom_w2(x);
r += c3 * catrom_w3(x);
return r;
template <class T> __device__ T catRomFilter(float x, T c0, T c1, T c2, T c3)
{
T r;
r = c0 * catrom_w0(x);
r += c1 * catrom_w1(x);
r += c2 * catrom_w2(x);
r += c3 * catrom_w3(x);
return r;
}
// Note - can't use bilinear trick here because of negative lobes
template <class T, class R> // texture data type, return type
__device__ R tex2DCatRom(const cudaTextureObject_t tex, float x, float y) {
x -= 0.5f;
y -= 0.5f;
float px = floorf(x);
float py = floorf(y);
float fx = x - px;
float fy = y - py;
template <class T, class R> // texture data type, return type
__device__ R tex2DCatRom(const cudaTextureObject_t tex, float x, float y)
{
x -= 0.5f;
y -= 0.5f;
float px = floorf(x);
float py = floorf(y);
float fx = x - px;
float fy = y - py;
return catRomFilter<R>(
fy, catRomFilter<R>(
fx, tex2D<R>(tex, px - 1, py - 1), tex2D<R>(tex, px, py - 1),
tex2D<R>(tex, px + 1, py - 1), tex2D<R>(tex, px + 2, py - 1)),
catRomFilter<R>(fx, tex2D<R>(tex, px - 1, py), tex2D<R>(tex, px, py),
tex2D<R>(tex, px + 1, py), tex2D<R>(tex, px + 2, py)),
catRomFilter<R>(fx, tex2D<R>(tex, px - 1, py + 1),
tex2D<R>(tex, px, py + 1), tex2D<R>(tex, px + 1, py + 1),
tex2D<R>(tex, px + 2, py + 1)),
catRomFilter<R>(fx, tex2D<R>(tex, px - 1, py + 2),
tex2D<R>(tex, px, py + 2), tex2D<R>(tex, px + 1, py + 2),
tex2D<R>(tex, px + 2, py + 2)));
return catRomFilter<R>(
fy,
catRomFilter<R>(fx,
tex2D<R>(tex, px - 1, py - 1),
tex2D<R>(tex, px, py - 1),
tex2D<R>(tex, px + 1, py - 1),
tex2D<R>(tex, px + 2, py - 1)),
catRomFilter<R>(
fx, tex2D<R>(tex, px - 1, py), tex2D<R>(tex, px, py), tex2D<R>(tex, px + 1, py), tex2D<R>(tex, px + 2, py)),
catRomFilter<R>(fx,
tex2D<R>(tex, px - 1, py + 1),
tex2D<R>(tex, px, py + 1),
tex2D<R>(tex, px + 1, py + 1),
tex2D<R>(tex, px + 2, py + 1)),
catRomFilter<R>(fx,
tex2D<R>(tex, px - 1, py + 2),
tex2D<R>(tex, px, py + 2),
tex2D<R>(tex, px + 1, py + 2),
tex2D<R>(tex, px + 2, py + 2)));
}
// test functions
// render image using normal bilinear texture lookup
__global__ void d_render(uchar4 *d_output, uint width, uint height, float tx,
float ty, float scale, float cx, float cy,
cudaTextureObject_t texObj) {
uint x = __umul24(blockIdx.x, blockDim.x) + threadIdx.x;
uint y = __umul24(blockIdx.y, blockDim.y) + threadIdx.y;
uint i = __umul24(y, width) + x;
__global__ void d_render(uchar4 *d_output,
uint width,
uint height,
float tx,
float ty,
float scale,
float cx,
float cy,
cudaTextureObject_t texObj)
{
uint x = __umul24(blockIdx.x, blockDim.x) + threadIdx.x;
uint y = __umul24(blockIdx.y, blockDim.y) + threadIdx.y;
uint i = __umul24(y, width) + x;
float u = (x - cx) * scale + cx + tx;
float v = (y - cy) * scale + cy + ty;
float u = (x - cx) * scale + cx + tx;
float v = (y - cy) * scale + cy + ty;
if ((x < width) && (y < height)) {
// write output color
float c = tex2D<float>(texObj, u, v);
// float c = tex2DBilinear<uchar, float>(tex, u, v);
// float c = tex2DBilinearGather<uchar, uchar4>(tex2, u, v, 0) / 255.0f;
d_output[i] = make_uchar4(c * 0xff, c * 0xff, c * 0xff, 0);
}
if ((x < width) && (y < height)) {
// write output color
float c = tex2D<float>(texObj, u, v);
// float c = tex2DBilinear<uchar, float>(tex, u, v);
// float c = tex2DBilinearGather<uchar, uchar4>(tex2, u, v, 0) / 255.0f;
d_output[i] = make_uchar4(c * 0xff, c * 0xff, c * 0xff, 0);
}
}
// render image using bicubic texture lookup
__global__ void d_renderBicubic(uchar4 *d_output, uint width, uint height,
float tx, float ty, float scale, float cx,
float cy, cudaTextureObject_t texObj) {
uint x = __umul24(blockIdx.x, blockDim.x) + threadIdx.x;
uint y = __umul24(blockIdx.y, blockDim.y) + threadIdx.y;
uint i = __umul24(y, width) + x;
__global__ void d_renderBicubic(uchar4 *d_output,
uint width,
uint height,
float tx,
float ty,
float scale,
float cx,
float cy,
cudaTextureObject_t texObj)
{
uint x = __umul24(blockIdx.x, blockDim.x) + threadIdx.x;
uint y = __umul24(blockIdx.y, blockDim.y) + threadIdx.y;
uint i = __umul24(y, width) + x;
float u = (x - cx) * scale + cx + tx;
float v = (y - cy) * scale + cy + ty;
float u = (x - cx) * scale + cx + tx;
float v = (y - cy) * scale + cy + ty;
if ((x < width) && (y < height)) {
// write output color
float c = tex2DBicubic<uchar, float>(texObj, u, v);
d_output[i] = make_uchar4(c * 0xff, c * 0xff, c * 0xff, 0);
}
if ((x < width) && (y < height)) {
// write output color
float c = tex2DBicubic<uchar, float>(texObj, u, v);
d_output[i] = make_uchar4(c * 0xff, c * 0xff, c * 0xff, 0);
}
}
// render image using fast bicubic texture lookup
__global__ void d_renderFastBicubic(uchar4 *d_output, uint width, uint height,
float tx, float ty, float scale, float cx,
float cy, cudaTextureObject_t texObj) {
uint x = __umul24(blockIdx.x, blockDim.x) + threadIdx.x;
uint y = __umul24(blockIdx.y, blockDim.y) + threadIdx.y;
uint i = __umul24(y, width) + x;
__global__ void d_renderFastBicubic(uchar4 *d_output,
uint width,
uint height,
float tx,
float ty,
float scale,
float cx,
float cy,
cudaTextureObject_t texObj)
{
uint x = __umul24(blockIdx.x, blockDim.x) + threadIdx.x;
uint y = __umul24(blockIdx.y, blockDim.y) + threadIdx.y;
uint i = __umul24(y, width) + x;
float u = (x - cx) * scale + cx + tx;
float v = (y - cy) * scale + cy + ty;
float u = (x - cx) * scale + cx + tx;
float v = (y - cy) * scale + cy + ty;
if ((x < width) && (y < height)) {
// write output color
float c = tex2DFastBicubic<uchar, float>(texObj, u, v);
d_output[i] = make_uchar4(c * 0xff, c * 0xff, c * 0xff, 0);
}
if ((x < width) && (y < height)) {
// write output color
float c = tex2DFastBicubic<uchar, float>(texObj, u, v);
d_output[i] = make_uchar4(c * 0xff, c * 0xff, c * 0xff, 0);
}
}
// render image using Catmull-Rom texture lookup
__global__ void d_renderCatRom(uchar4 *d_output, uint width, uint height,
float tx, float ty, float scale, float cx,
float cy, cudaTextureObject_t texObj) {
uint x = __umul24(blockIdx.x, blockDim.x) + threadIdx.x;
uint y = __umul24(blockIdx.y, blockDim.y) + threadIdx.y;
uint i = __umul24(y, width) + x;
__global__ void d_renderCatRom(uchar4 *d_output,
uint width,
uint height,
float tx,
float ty,
float scale,
float cx,
float cy,
cudaTextureObject_t texObj)
{
uint x = __umul24(blockIdx.x, blockDim.x) + threadIdx.x;
uint y = __umul24(blockIdx.y, blockDim.y) + threadIdx.y;
uint i = __umul24(y, width) + x;
float u = (x - cx) * scale + cx + tx;
float v = (y - cy) * scale + cy + ty;
float u = (x - cx) * scale + cx + tx;
float v = (y - cy) * scale + cy + ty;
if ((x < width) && (y < height)) {
// write output color
float c = tex2DCatRom<uchar, float>(texObj, u, v);
d_output[i] = make_uchar4(c * 0xff, c * 0xff, c * 0xff, 0);
}
if ((x < width) && (y < height)) {
// write output color
float c = tex2DCatRom<uchar, float>(texObj, u, v);
d_output[i] = make_uchar4(c * 0xff, c * 0xff, c * 0xff, 0);
}
}
#endif // _BICUBICTEXTURE_KERNEL_CUH_
#endif // _BICUBICTEXTURE_KERNEL_CUH_