1

我正在为我的硕士项目试验 OpenCL,在 GPU 上实现基于图像的照明算法。到目前为止,我没有什么大问题,但今天我遇到了一个非常烦人的问题。当我调用 build 方法时,它只是卡住了……我的一个内核以 100% 的速度运行,就像卡在无限循环中一样。我试图编译的代码如下:

#define M_PI           3.14159265358979323846

constant sampler_t sampler = CLK_NORMALIZED_COORDS_TRUE |
                             CLK_ADDRESS_CLAMP_TO_EDGE |
                             CLK_FILTER_NEAREST;

#pragma OPENCL EXTENSION cl_amd_printf : enable


typedef struct __attribute__ ((packed)) s_ray {
    float3 origin;
    float3 direction;
} Ray;

typedef struct __attribute__ ((packed)) s_sphere {
    float3 center;
    float radius;
} Sphere;

typedef struct s_hit {
    Ray ray;
    float t;
} Hit;

typedef float4 Color;
typedef float3 Normal;



void ray_sphere_intersection(Hit* h, Ray ray, Sphere sphere) {

    h->ray = ray;

    float A = dot(ray.direction, ray.direction);
    float B = 2 * dot(ray.direction, ray.origin);
    float C = dot(ray.origin, ray.origin) - sphere.radius * sphere.radius;

    float inv2A = 1/(2 * A);

    float delta = B*B - 4*A*C;

    if (delta < 0) {
        h->t = -1;
    }
    else {
        float sqrt_d = sqrt(delta);
        float t1 = (-B - sqrt_d) * inv2A;
        float t2 = (-B + sqrt_d) * inv2A;

        h->t = (t1 > t2 ? t1 : t2);
    }
    return h;
}

void reflection(Ray* ref, Ray r, Normal n) {
    ref->direction = 2 * dot(r.direction, n) * n - r.direction;
    ref->origin = n;
    return ref;
}

Color map(image2d_t env, Hit inter) {
    Normal n = normalize(inter.ray.origin + inter.t * inter.ray.direction);
    Ray ref; 
    reflection(&ref, inter.ray, n);
    float theta = acos(ref.direction.s1);
    float phi = atan2(ref.direction.s0, ref.direction.s2);
    float x = theta/M_PI;
    float y = (phi + M_PI)/(2 * M_PI);
    Color c = read_imagef(env, sampler, (float2)(x,y));
    return c;
}

kernel void ray_cast(read_only image2d_t env, global float* Ls, global Ray* rays, int nb_prim, global Sphere* spheres) {

    int p = get_global_id(0);

    int z = 0;

    //for (int i = 0; i < nb_prim; ++i) {
        //printf("%f\n", ray_sphere_intersection(rays[p], spheres[0]));
        Hit h; 
            ray_sphere_intersection(&h, rays[p], spheres[0]);
        if (h.t != -1) {
            Color c = map(env, h);
            Ls[p] = c.s0;
            Ls[p] = c.s1;
            Ls[p] = c.s2;
            //Ls[p] = 1.0;
        }
        else {
            for (int i = 0; i < 3; ++i)
                Ls[p + i] = 0;
        }
    //}

}

我在 Linux Mint Debian 版上运行最新版本的 SDK 和催化剂。我在这里一无所知,希望有人可以帮助我。我的显卡是HD 5770。

4

0 回答 0