diff options
author | Sv. Lockal <lockalsash@gmail.com> | 2014-01-13 18:21:34 +0400 |
---|---|---|
committer | Sv. Lockal <lockalsash@gmail.com> | 2014-01-13 18:31:02 +0400 |
commit | 9cf6946d3113fe1a8b61954fd724f4db6a4a8e8e (patch) | |
tree | f8ee3ca1007cbd94e39577075452400455e3995d /intern/cycles/kernel/svm/svm_image.h | |
parent | 5ad5883ce369e48fe3dfabfdd0bbacbc4eb28b17 (diff) |
Fix cycles texture crash on win x86-64 + msvc 11
Use union for __m128 aliasing; while gcc supports no-strict-aliasing attribute, unions are the most common way to deal with __m128 in msvc.
Diffstat (limited to 'intern/cycles/kernel/svm/svm_image.h')
-rw-r--r-- | intern/cycles/kernel/svm/svm_image.h | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index 06228cdbea9..2687e03e843 100644 --- a/intern/cycles/kernel/svm/svm_image.h +++ b/intern/cycles/kernel/svm/svm_image.h @@ -112,14 +112,13 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb, uint use_alpha) { +#if defined(__KERNEL_CPU__) && defined(__KERNEL_SSE2__) + union { float4 rgba; __m128 m128; } r = { kernel_tex_image_interp(id, x, y) }; +#elif defined(__KERNEL_CPU__) + float4 r = kernel_tex_image_interp(id, x, y); +#else float4 r; -#ifdef __KERNEL_CPU__ - r = kernel_tex_image_interp(id, x, y); -#ifdef __KERNEL_SSE2__ - __m128 *rv = (__m128 *)&r; -#endif -#else /* not particularly proud of this massive switch, what are the * alternatives? * - use a single big 1D texture, and do our own lookup/filtering @@ -236,14 +235,24 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, } #endif - if(use_alpha && r.w != 1.0f && r.w != 0.0f) { #ifdef __KERNEL_SSE2__ - float alpha = r.w; - *rv = _mm_div_ps(*rv, _mm_set1_ps(alpha)); + if(use_alpha && r.rgba.w != 1.0f && r.rgba.w != 0.0f) { + float alpha = r.rgba.w; + r.m128 = _mm_div_ps(r.m128, _mm_set1_ps(alpha)); if(id >= TEX_NUM_FLOAT_IMAGES) - *rv = _mm_min_ps(*rv, _mm_set1_ps(1.0f)); - r.w = alpha; + r.m128 = _mm_min_ps(r.m128, _mm_set1_ps(1.0f)); + r.rgba.w = alpha; + } + + if(srgb) { + float alpha = r.rgba.w; + r.m128 = color_srgb_to_scene_linear(r.m128); + r.rgba.w = alpha; + } + + return r.rgba; #else + if(use_alpha && r.w != 1.0f && r.w != 0.0f) { float invw = 1.0f/r.w; r.x *= invw; r.y *= invw; @@ -254,22 +263,16 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, r.y = min(r.y, 1.0f); r.z = min(r.z, 1.0f); } -#endif } if(srgb) { -#ifdef __KERNEL_SSE2__ - float alpha = r.w; - *rv = color_srgb_to_scene_linear(*rv); - r.w = alpha; -#else r.x = color_srgb_to_scene_linear(r.x); r.y = color_srgb_to_scene_linear(r.y); r.z = color_srgb_to_scene_linear(r.z); -#endif } return r; +#endif } #endif |