diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-08-11 10:52:39 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-08-11 11:12:06 +0300 |
commit | fdc43f993da8e89a08bc018315aaa4468b29a456 (patch) | |
tree | 37602ddec04f18c08083dd83d571a56cc421630a /intern | |
parent | a501668cc5f11f15af9fb47ea3c8c7fc910e8722 (diff) |
Cycles: Use static assert to control structures alignment
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/kernel/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 12 | ||||
-rw-r--r-- | intern/cycles/util/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/cycles/util/util_debug.h | 2 | ||||
-rw-r--r-- | intern/cycles/util/util_static_assert.h | 64 |
5 files changed, 80 insertions, 0 deletions
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 7bef247d3bd..9317bfbb703 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -176,6 +176,7 @@ set(SRC_UTIL_HEADERS ../util/util_half.h ../util/util_math.h ../util/util_math_fast.h + ../util/util_static_assert.h ../util/util_transform.h ../util/util_texture.h ../util/util_types.h diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 2ae42a83dc9..a94d544b873 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -19,6 +19,7 @@ #include "kernel_math.h" #include "svm/svm_types.h" +#include "util_static_assert.h" #ifndef __KERNEL_GPU__ # define __KERNEL_CPU__ @@ -986,6 +987,7 @@ typedef struct KernelCamera { int pad; } KernelCamera; +static_assert_align(KernelCamera, 16); typedef struct KernelFilm { float exposure; @@ -1040,6 +1042,7 @@ typedef struct KernelFilm { int pass_pad3; #endif } KernelFilm; +static_assert_align(KernelFilm, 16); typedef struct KernelBackground { /* only shader index */ @@ -1053,6 +1056,7 @@ typedef struct KernelBackground { float ao_distance; float ao_pad1, ao_pad2; } KernelBackground; +static_assert_align(KernelBackground, 16); typedef struct KernelIntegrator { /* emission */ @@ -1123,6 +1127,7 @@ typedef struct KernelIntegrator { int pad1; int pad2; } KernelIntegrator; +static_assert_align(KernelIntegrator, 16); typedef struct KernelBVH { /* root node */ @@ -1134,6 +1139,7 @@ typedef struct KernelBVH { int use_qbvh; int pad1, pad2; } KernelBVH; +static_assert_align(KernelBVH, 16); typedef enum CurveFlag { /* runtime flags */ @@ -1153,11 +1159,13 @@ typedef struct KernelCurves { float minimum_width; float maximum_width; } KernelCurves; +static_assert_align(KernelCurves, 16); typedef struct KernelTables { int beckmann_offset; int pad1, pad2, pad3; } KernelTables; +static_assert_align(KernelTables, 16); typedef struct KernelData { KernelCamera cam; @@ -1168,8 +1176,12 @@ typedef struct KernelData { KernelCurves curve; KernelTables tables; } KernelData; +static_assert_align(KernelData, 16); #ifdef __KERNEL_DEBUG__ +/* NOTE: This is a runtime-only struct, alignment is not + * really important here. + */ typedef ccl_addr_space struct DebugData { // Total number of BVH node traversal steps and primitives intersections // for the camera rays. diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt index e6140b3ed09..7eb5a9c7c64 100644 --- a/intern/cycles/util/CMakeLists.txt +++ b/intern/cycles/util/CMakeLists.txt @@ -71,6 +71,7 @@ set(SRC_HEADERS util_ssef.h util_ssei.h util_stack_allocator.h + util_static_assert.h util_stats.h util_string.h util_system.h diff --git a/intern/cycles/util/util_debug.h b/intern/cycles/util/util_debug.h index 1787ff648ee..73fd228b5d9 100644 --- a/intern/cycles/util/util_debug.h +++ b/intern/cycles/util/util_debug.h @@ -20,6 +20,8 @@ #include <cassert> #include <iostream> +#include "util_static_assert.h" + CCL_NAMESPACE_BEGIN /* Global storage for all sort of flags used to fine-tune behavior of particular diff --git a/intern/cycles/util/util_static_assert.h b/intern/cycles/util/util_static_assert.h new file mode 100644 index 00000000000..1b945705145 --- /dev/null +++ b/intern/cycles/util/util_static_assert.h @@ -0,0 +1,64 @@ +/* + * Copyright 2011-2016 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTIL_STATIC_ASSERT_H__ +#define __UTIL_STATIC_ASSERT_H__ + +CCL_NAMESPACE_BEGIN + +/* TODO(sergey): In theory CUDA might work with own static assert + * implementation since it's just pure C++. + */ +#ifndef __KERNEL_GPU__ +# if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) +/* C++11 has built-in static_assert() */ +# else /* C++11 or MSVC2015 */ +template <bool Test> class StaticAssertFailure; +template <> class StaticAssertFailure<true> {}; +# define _static_assert_private_glue_impl(A, B) A ## B +# define _static_assert_glue(A, B) _static_assert_private_glue_impl(A, B) +# ifdef __COUNTER__ +# define static_assert(condition, message) \ + enum {_static_assert_glue(q_static_assert_result, __COUNTER__) = sizeof(StaticAssertFailure<!!(condition)>)} // NOLINT +# else /* __COUNTER__ */ +# define static_assert(condition, message) \ + enum {_static_assert_glue(q_static_assert_result, __LINE__) = sizeof(StaticAssertFailure<!!(condition)>)} // NOLINT +# endif /* __COUNTER__ */ +# endif /* C++11 or MSVC2015 */ +#else /* __KERNEL_GPU__ */ +# define static_assert(statement, message) +#endif /* __KERNEL_GPU__ */ + +/* TODO(sergey): For until C++11 is a bare minimum for us, + * we do a bit of a trickery to show meaningful message so + * it's more or less clear what's wrong when building without + * C++11. + * + * The thing here is: our non-C++11 implementation doesn't + * have a way to print any message after preprocessor + * substitution so we rely on the message which is passed to + * static_assert() since that's the only message visible when + * compilation fails. + * + * After C++11 bump it should be possible to glue structure + * name to the error message, + */ +# define static_assert_align(st, align) \ + static_assert((sizeof(st) % (align) == 0), "Structure must be strictly aligned") // NOLINT + +CCL_NAMESPACE_END + +#endif /* __UTIL_STATIC_ASSERT_H__ */ |