Cycles: Make all #include statements relative to cycles source directory
[blender.git] / intern / cycles / device / opencl / opencl_mega.cpp
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifdef WITH_OPENCL
18
19 #include "device/opencl/opencl.h"
20
21 #include "render/buffers.h"
22
23 #include "kernel/kernel_types.h"
24
25 #include "util/util_md5.h"
26 #include "util/util_path.h"
27 #include "util/util_time.h"
28
29 CCL_NAMESPACE_BEGIN
30
31 class OpenCLDeviceMegaKernel : public OpenCLDeviceBase
32 {
33 public:
34         OpenCLProgram path_trace_program;
35
36         OpenCLDeviceMegaKernel(DeviceInfo& info, Stats &stats, bool background_)
37         : OpenCLDeviceBase(info, stats, background_),
38           path_trace_program(this, "megakernel", "kernel.cl", "-D__COMPILE_ONLY_MEGAKERNEL__ ")
39         {
40         }
41
42         virtual bool show_samples() const {
43                 return true;
44         }
45
46         virtual bool load_kernels(const DeviceRequestedFeatures& /*requested_features*/,
47                                   vector<OpenCLProgram*> &programs)
48         {
49                 path_trace_program.add_kernel(ustring("path_trace"));
50                 programs.push_back(&path_trace_program);
51                 return true;
52         }
53
54         ~OpenCLDeviceMegaKernel()
55         {
56                 task_pool.stop();
57                 path_trace_program.release();
58         }
59
60         void path_trace(RenderTile& rtile, int sample)
61         {
62                 /* Cast arguments to cl types. */
63                 cl_mem d_data = CL_MEM_PTR(const_mem_map["__data"]->device_pointer);
64                 cl_mem d_buffer = CL_MEM_PTR(rtile.buffer);
65                 cl_mem d_rng_state = CL_MEM_PTR(rtile.rng_state);
66                 cl_int d_x = rtile.x;
67                 cl_int d_y = rtile.y;
68                 cl_int d_w = rtile.w;
69                 cl_int d_h = rtile.h;
70                 cl_int d_offset = rtile.offset;
71                 cl_int d_stride = rtile.stride;
72
73                 /* Sample arguments. */
74                 cl_int d_sample = sample;
75
76                 cl_kernel ckPathTraceKernel = path_trace_program(ustring("path_trace"));
77
78                 cl_uint start_arg_index =
79                         kernel_set_args(ckPathTraceKernel,
80                                         0,
81                                         d_data,
82                                         d_buffer,
83                                         d_rng_state);
84
85 #define KERNEL_TEX(type, ttype, name) \
86                 set_kernel_arg_mem(ckPathTraceKernel, &start_arg_index, #name);
87 #include "kernel/kernel_textures.h"
88 #undef KERNEL_TEX
89
90                 start_arg_index += kernel_set_args(ckPathTraceKernel,
91                                                    start_arg_index,
92                                                    d_sample,
93                                                    d_x,
94                                                    d_y,
95                                                    d_w,
96                                                    d_h,
97                                                    d_offset,
98                                                    d_stride);
99
100                 enqueue_kernel(ckPathTraceKernel, d_w, d_h);
101         }
102
103         void thread_run(DeviceTask *task)
104         {
105                 if(task->type == DeviceTask::FILM_CONVERT) {
106                         film_convert(*task, task->buffer, task->rgba_byte, task->rgba_half);
107                 }
108                 else if(task->type == DeviceTask::SHADER) {
109                         shader(*task);
110                 }
111                 else if(task->type == DeviceTask::PATH_TRACE) {
112                         RenderTile tile;
113                         /* Keep rendering tiles until done. */
114                         while(task->acquire_tile(this, tile)) {
115                                 int start_sample = tile.start_sample;
116                                 int end_sample = tile.start_sample + tile.num_samples;
117
118                                 for(int sample = start_sample; sample < end_sample; sample++) {
119                                         if(task->get_cancel()) {
120                                                 if(task->need_finish_queue == false)
121                                                         break;
122                                         }
123
124                                         path_trace(tile, sample);
125
126                                         tile.sample = sample + 1;
127
128                                         task->update_progress(&tile, tile.w*tile.h);
129                                 }
130
131                                 /* Complete kernel execution before release tile */
132                                 /* This helps in multi-device render;
133                                  * The device that reaches the critical-section function
134                                  * release_tile waits (stalling other devices from entering
135                                  * release_tile) for all kernels to complete. If device1 (a
136                                  * slow-render device) reaches release_tile first then it would
137                                  * stall device2 (a fast-render device) from proceeding to render
138                                  * next tile.
139                                  */
140                                 clFinish(cqCommandQueue);
141
142                                 task->release_tile(tile);
143                         }
144                 }
145         }
146 };
147
148 Device *opencl_create_mega_device(DeviceInfo& info, Stats& stats, bool background)
149 {
150         return new OpenCLDeviceMegaKernel(info, stats, background);
151 }
152
153 CCL_NAMESPACE_END
154
155 #endif