ef28f7b6d91d547ea237fd830718710be313d403
[blender.git] / intern / cycles / kernel / SConscript
1 #!/usr/bin/env python
2 #
3 # ***** BEGIN GPL LICENSE BLOCK *****
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software Foundation,
17 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 #
19 # The Original Code is Copyright (C) 2011, Blender Foundation
20 # All rights reserved.
21 #
22 # The Original Code is: all of this file.
23 #
24 # Contributor(s): Nathan Letwory.
25 #
26 # ***** END GPL LICENSE BLOCK *****
27
28 import re
29 import subprocess
30 import sys
31 import os
32 import Blender as B
33
34 def normpath(path):
35     return os.path.abspath(os.path.normpath(path))
36
37 Import ('env')
38
39 kernel_binaries = []
40
41 #Bitness
42 if B.bitness == 32:
43     bits = 32
44 else:
45     bits = 64
46
47 if env['WITH_BF_CYCLES_CUDA_BINARIES']:
48     kernel = env.Clone()
49
50     # cuda info
51     nvcc = env['BF_CYCLES_CUDA_NVCC']
52     cuda_archs = env['BF_CYCLES_CUDA_BINARIES_ARCH']
53
54     # build directory
55     root_build_dir = normpath(env['BF_BUILDDIR'])
56     build_dir = os.path.join(root_build_dir, 'intern/cycles/kernel')
57
58     # source directories and files
59     source_dir = Dir('.').srcnode().path
60     kernel_file = os.path.join(source_dir, "kernel.cu")
61     util_dir = os.path.join(source_dir, "../util")
62     svm_dir = os.path.join(source_dir, "../svm")
63     geom_dir = os.path.join(source_dir, "../geom")
64     closure_dir = os.path.join(source_dir, "../closure")
65
66     # get CUDA version
67     nvcc_pipe = subprocess.Popen([nvcc, "--version"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
68     output, erroroutput = nvcc_pipe.communicate()
69     cuda_major_minor = re.findall(r'release (\d+).(\d+)', output)[0]
70     cuda_version = int(cuda_major_minor[0])*10 + int(cuda_major_minor[1])
71
72     if cuda_version != 60:
73         print("CUDA version %d.%d detected, build may succeed but only CUDA 6.0 is officially supported." % (cuda_version/10, cuda_version%10))
74
75     # nvcc flags
76     nvcc_flags = "-m%s" % (bits)
77     nvcc_flags += " --cubin --ptxas-options=\"-v\" --use_fast_math"
78     nvcc_flags += " -D__KERNEL_CUDA_VERSION__=%d" % (cuda_version)
79     nvcc_flags += " -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC"
80     nvcc_flags += " -I \"%s\" -I \"%s\" -I \"%s\" -I \"%s\"" % (util_dir, svm_dir, geom_dir, closure_dir)
81
82     # dependencies
83     dependencies = ['kernel.cu'] + kernel.Glob('*.h') + kernel.Glob('../util/*.h') + kernel.Glob('svm/*.h') + kernel.Glob('geom/*.h') + kernel.Glob('closure/*.h')
84     last_cubin_file = None
85
86     # add command for each cuda architecture
87     for arch in cuda_archs:
88         if cuda_version < 60 and arch == "sm_50":
89             print("Can't build kernel for CUDA sm_50 architecture, skipping")
90             continue
91
92         cubin_file = os.path.join(build_dir, "kernel_%s.cubin" % arch)
93
94         if env['BF_CYCLES_CUDA_ENV']:
95             MS_SDK = "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Bin\\SetEnv.cmd"
96             command = "\"%s\" & \"%s\" -arch=%s %s \"%s\" -o \"%s\"" % (MS_SDK, nvcc, arch, nvcc_flags, kernel_file, cubin_file)
97         else:
98             command = "\"%s\" -arch=%s %s \"%s\" -o \"%s\"" % (nvcc, arch, nvcc_flags, kernel_file, cubin_file)
99
100         kernel.Command(cubin_file, 'kernel.cu', command)
101         kernel.Depends(cubin_file, dependencies)
102
103         kernel_binaries.append(cubin_file)
104         
105         if not env['WITH_BF_CYCLES_CUDA_THREADED_COMPILE']:
106             # trick to compile one kernel at a time to reduce memory usage
107             if last_cubin_file:
108                 kernel.Depends(cubin_file, last_cubin_file)
109             last_cubin_file = cubin_file
110
111 Return('kernel_binaries')
112