-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cu
133 lines (106 loc) · 4.22 KB
/
main.cu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "common.cuh"
#include <vector>
#include <fstream>
#define checkCudaErrors(val) check_cuda( (val), #val, __FILE__, __LINE__ )
void check_cuda(cudaError_t result, char const *const func, const char *const file, int const line)
{
if (result) {
std::cerr << "CUDA error = " << static_cast<unsigned int>(result) << " at " <<
file << ":" << line << " '" << func << "' \n";
// Make sure we call CUDA Device Reset before exiting
cudaDeviceReset();
exit(99);
}
}
__global__ void render_init(camera** d_camera, int *d_tasks_done)
{
// *d_camera = new camera(2.0, 1.0);
vec3double lookfrom(13, 2, 3), lookat(0, 0, 0), vup(0, 1, 0);
double dist_to_focus = 10.0;
double aperture = 0.1;
*d_camera = new camera(lookfrom, lookat, vup, 20, (double)IMAGE_WIDTH/IMAGE_HEIGHT, aperture, dist_to_focus);
*d_tasks_done = 0;
}
__global__ void render_free(camera** d_camera)
{
delete *d_camera;
}
inline double random_double()
{
return rand() / (RAND_MAX + 1.0);
}
inline double random_double(double min, double max)
{
return min + (max - min) * random_double();
}
inline vec3double random_vector()
{
return vec3double(random_double(), random_double(), random_double());
}
inline vec3double random_vector(double min, double max)
{
return vec3double(random_double(min, max), random_double(min, max), random_double(min, max));
}
int main()
{
std::ofstream outfile;
outfile.open("result.ppm");
dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
dim3 dimGrid(IMAGE_WIDTH/BLOCK_SIZE+1, IMAGE_HEIGHT/BLOCK_SIZE+1);
// buffer
int pixel_size = sizeof(vec3double) * IMAGE_WIDTH * IMAGE_HEIGHT;
vec3double *h_pixels = (vec3double*)malloc(pixel_size);
vec3double *d_pixels;
checkCudaErrors(cudaMallocManaged((void**)&d_pixels, pixel_size));
// cameras
camera** d_camera;
checkCudaErrors(cudaMallocManaged((void**)&d_camera, sizeof(camera*)));
// task counter
int* d_tasks_done;
checkCudaErrors(cudaMallocManaged((void**)&d_tasks_done, sizeof(int)));
// spheres
std::vector<sphere> h_spheres;
// ground
// srand(time(NULL));
h_spheres.push_back(sphere(vec3double(0, -1000, 0), 1000, vec3double(0.5)));
for (int a = -11; a < 11; a++)
for (int b = -11; b < 11; b++){
double choose_mat = random_double();
vec3double center(a + 0.9 * random_double(), 0.2, b + 0.9 * random_double());
if ((center - vec3double(4, 0.2, 0)).length() > 0.9){
if (choose_mat < 0.8)
h_spheres.push_back(sphere(center, 0.2, random_vector()*random_vector()));
else if (choose_mat < 0.95)
h_spheres.push_back(sphere(center, 0.2, random_vector(0.5, 1)).as_metal(random_double(0, 0.5)));
else
h_spheres.push_back(sphere(center, 0.2, random_vector()*random_vector()).as_dielectric(1.5));
}
}
h_spheres.push_back(sphere(vec3double(0, 1, 0), 1, vec3double(1)).as_dielectric(1.5));
h_spheres.push_back(sphere(vec3double(-4, 1, 0), 1, vec3double(0.4, 0.2, 0.1)));
h_spheres.push_back(sphere(vec3double(4, 1, 0), 1, vec3double(0.7, 0.6, 0.5)).as_metal(0.0));
sphere* d_spheres;
if (h_spheres.size()){
checkCudaErrors(cudaMallocManaged((void**)&d_spheres, sizeof(sphere) * h_spheres.size()));
checkCudaErrors(cudaMemcpy(d_spheres, &h_spheres[0], sizeof(sphere) * h_spheres.size(), cudaMemcpyHostToDevice));
}
// init
render_init<<<1, 1>>>(d_camera, d_tasks_done);
// core
std::cout << "\r0.000000%";
outfile << "P3\n" << IMAGE_WIDTH << " " << IMAGE_HEIGHT << "\n255\n";
render<<<dimGrid, dimBlock>>>(d_pixels, d_camera, d_spheres, h_spheres.size(), d_tasks_done);
checkCudaErrors(cudaGetLastError());
checkCudaErrors(cudaDeviceSynchronize());
checkCudaErrors(cudaMemcpy(h_pixels, d_pixels, pixel_size, cudaMemcpyDeviceToHost));
std::cout << "\r100.000000%";
write_pixels(outfile, h_pixels);
std::cout << "\ndone\n";
outfile.close();
render_free<<<1, 1>>>(d_camera);
checkCudaErrors(cudaFree(d_pixels));
checkCudaErrors(cudaFree(d_camera));
checkCudaErrors(cudaFree(d_tasks_done));
if (h_spheres.size())
checkCudaErrors(cudaFree(d_spheres));
}