Cycles: OpenCL 3d textures support.
authorHristo Gueorguiev <>
Sat, 22 Oct 2016 21:38:42 +0000 (23:38 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Sat, 22 Oct 2016 21:49:29 +0000 (23:49 +0200)
Note that volume rendering is not supported yet, this is a step towards that.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2299

intern/cycles/kernel/CMakeLists.txt
intern/cycles/kernel/geom/geom_volume.h
intern/cycles/kernel/kernel_image_opencl.h [new file with mode: 0644]
intern/cycles/kernel/kernels/opencl/kernel.cl
intern/cycles/kernel/split/kernel_split_common.h
intern/cycles/kernel/svm/svm_image.h
intern/cycles/kernel/svm/svm_voxel.h
intern/cycles/render/image.cpp

index e4341c8aca172c915da81d13d192d9cc9527db3b..694f19a808ae84bb76e372c25263940ba3440dba 100644 (file)
@@ -57,6 +57,7 @@ set(SRC_HEADERS
        kernel_emission.h
        kernel_film.h
        kernel_globals.h
+       kernel_image_opencl.h
        kernel_jitter.h
        kernel_light.h
        kernel_math.h
index fd97a63efb50a323b6fb11e977ba3c3169abfa78..03724c955beda09f884fb8d70691dae303f5e30d 100644 (file)
@@ -29,7 +29,7 @@ CCL_NAMESPACE_BEGIN
 
 /* Return position normalized to 0..1 in mesh bounds */
 
-#if defined(__KERNEL_GPU__) && __CUDA_ARCH__ < 300
+#if defined(__KERNEL_CUDA__) && __CUDA_ARCH__ < 300
 ccl_device float4 volume_image_texture_3d(int id, float x, float y, float z)
 {
        float4 r;
@@ -42,7 +42,7 @@ ccl_device float4 volume_image_texture_3d(int id, float x, float y, float z)
        }
        return r;
 }
-#endif  /* __KERNEL_GPU__ */
+#endif  /* __KERNEL_CUDA__ */
 
 ccl_device_inline float3 volume_normalized_position(KernelGlobals *kg,
                                                     const ShaderData *sd,
@@ -64,8 +64,8 @@ ccl_device_inline float3 volume_normalized_position(KernelGlobals *kg,
 
 ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
 {
-       float3 P = volume_normalized_position(kg, sd, sd->P);
-#ifdef __KERNEL_GPU__
+       float3 P = volume_normalized_position(kg, sd, ccl_fetch(sd, P));
+#ifdef __KERNEL_CUDA__
 #  if __CUDA_ARCH__ >= 300
        CUtexObject tex = kernel_tex_fetch(__bindless_mapping, desc.offset);
        float f = kernel_tex_image_interp_3d_float(tex, P.x, P.y, P.z);
@@ -73,6 +73,8 @@ ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd,
 #  else
        float4 r = volume_image_texture_3d(desc.offset, P.x, P.y, P.z);
 #  endif
+#elif defined(__KERNEL_OPENCL__)
+       float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z);
 #else
        float4 r;
        if(sd->flag & SD_VOLUME_CUBIC)
@@ -89,14 +91,16 @@ ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd,
 
 ccl_device float3 volume_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
 {
-       float3 P = volume_normalized_position(kg, sd, sd->P);
-#ifdef __KERNEL_GPU__
+       float3 P = volume_normalized_position(kg, sd, ccl_fetch(sd, P));
+#ifdef __KERNEL_CUDA__
 #  if __CUDA_ARCH__ >= 300
        CUtexObject tex = kernel_tex_fetch(__bindless_mapping, desc.offset);
        float4 r = kernel_tex_image_interp_3d_float4(tex, P.x, P.y, P.z);
 #  else
        float4 r = volume_image_texture_3d(desc.offset, P.x, P.y, P.z);
 #  endif
+#elif defined(__KERNEL_OPENCL__)
+       float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z);
 #else
        float4 r;
        if(sd->flag & SD_VOLUME_CUBIC)
diff --git a/intern/cycles/kernel/kernel_image_opencl.h b/intern/cycles/kernel/kernel_image_opencl.h
new file mode 100644 (file)
index 0000000..f6c31b2
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Copyright 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.
+ */
+
+
+/* For OpenCL all images are packed in a single array, and we do manual lookup
+ * and interpolation. */
+
+ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, int id, int offset)
+{
+       /* Float4 */
+       if(id < TEX_START_BYTE4_OPENCL) {
+               return kernel_tex_fetch(__tex_image_float4_packed, offset);
+       }
+       /* Byte4 */
+       else if(id < TEX_START_FLOAT_OPENCL) {
+               uchar4 r = kernel_tex_fetch(__tex_image_byte4_packed, offset);
+               float f = 1.0f/255.0f;
+               return make_float4(r.x*f, r.y*f, r.z*f, r.w*f);
+       }
+       /* Float */
+       else if(id < TEX_START_BYTE_OPENCL) {
+               float f = kernel_tex_fetch(__tex_image_float_packed, offset);
+               return make_float4(f, f, f, 1.0f);
+       }
+       /* Byte */
+       else {
+               uchar r = kernel_tex_fetch(__tex_image_byte_packed, offset);
+               float f = r * (1.0f/255.0f);
+               return make_float4(f, f, f, 1.0f);
+       }
+}
+
+ccl_device_inline int svm_image_texture_wrap_periodic(int x, int width)
+{
+       x %= width;
+       if(x < 0)
+               x += width;
+       return x;
+}
+
+ccl_device_inline int svm_image_texture_wrap_clamp(int x, int width)
+{
+       return clamp(x, 0, width-1);
+}
+
+ccl_device_inline float svm_image_texture_frac(float x, int *ix)
+{
+       int i = float_to_int(x) - ((x < 0.0f)? 1: 0);
+       *ix = i;
+       return x - (float)i;
+}
+
+ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, float y)
+{
+       uint4 info = kernel_tex_fetch(__tex_image_packed_info, id*2);
+       uint width = info.x;
+       uint height = info.y;
+       uint offset = info.z;
+
+       /* Image Options */
+       uint interpolation = (info.w & (1 << 0)) ? INTERPOLATION_CLOSEST : INTERPOLATION_LINEAR;
+       uint extension;
+       if(info.w & (1 << 1))
+               extension = EXTENSION_REPEAT;
+       else if(info.w & (1 << 2))
+               extension = EXTENSION_EXTEND;
+       else
+               extension = EXTENSION_CLIP;
+
+       float4 r;
+       int ix, iy, nix, niy;
+       if(interpolation == INTERPOLATION_CLOSEST) {
+               svm_image_texture_frac(x*width, &ix);
+               svm_image_texture_frac(y*height, &iy);
+
+               if(extension == EXTENSION_REPEAT) {
+                       ix = svm_image_texture_wrap_periodic(ix, width);
+                       iy = svm_image_texture_wrap_periodic(iy, height);
+               }
+               else {
+                       if(extension == EXTENSION_CLIP) {
+                               if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
+                                       return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+                               }
+                       }
+                       /* Fall through. */
+                       /* EXTENSION_EXTEND */
+                       ix = svm_image_texture_wrap_clamp(ix, width);
+                       iy = svm_image_texture_wrap_clamp(iy, height);
+               }
+
+               r = svm_image_texture_read(kg, id, offset + ix + iy*width);
+       }
+       else { /* INTERPOLATION_LINEAR */
+               float tx = svm_image_texture_frac(x*width - 0.5f, &ix);
+               float ty = svm_image_texture_frac(y*height - 0.5f, &iy);
+
+               if(extension == EXTENSION_REPEAT) {
+                       ix = svm_image_texture_wrap_periodic(ix, width);
+                       iy = svm_image_texture_wrap_periodic(iy, height);
+
+                       nix = svm_image_texture_wrap_periodic(ix+1, width);
+                       niy = svm_image_texture_wrap_periodic(iy+1, height);
+               }
+               else {
+                       if(extension == EXTENSION_CLIP) {
+                               if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
+                                       return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+                               }
+                       }
+                       nix = svm_image_texture_wrap_clamp(ix+1, width);
+                       niy = svm_image_texture_wrap_clamp(iy+1, height);
+                       ix = svm_image_texture_wrap_clamp(ix, width);
+                       iy = svm_image_texture_wrap_clamp(iy, height);
+               }
+
+               r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + iy*width);
+               r += (1.0f - ty)*tx*svm_image_texture_read(kg, id, offset + nix + iy*width);
+               r += ty*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + niy*width);
+               r += ty*tx*svm_image_texture_read(kg, id, offset + nix + niy*width);
+       }
+
+       return r;
+}
+
+
+ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, float y, float z)
+{
+       uint4 info = kernel_tex_fetch(__tex_image_packed_info, id*2);
+       uint width = info.x;
+       uint height = info.y;
+       uint offset = info.z;
+       uint depth = kernel_tex_fetch(__tex_image_packed_info, id*2+1).x;
+
+       /* Image Options */
+       uint interpolation = (info.w & (1 << 0)) ? INTERPOLATION_CLOSEST : INTERPOLATION_LINEAR;
+       uint extension;
+       if(info.w & (1 << 1))
+               extension = EXTENSION_REPEAT;
+       else if(info.w & (1 << 2))
+               extension = EXTENSION_EXTEND;
+       else
+               extension = EXTENSION_CLIP;
+
+       float4 r;
+       int ix, iy, iz, nix, niy, niz;
+       if(interpolation == INTERPOLATION_CLOSEST) {
+               svm_image_texture_frac(x*width, &ix);
+               svm_image_texture_frac(y*height, &iy);
+               svm_image_texture_frac(z*depth, &iz);
+
+               if (extension == EXTENSION_REPEAT) {
+                       ix = svm_image_texture_wrap_periodic(ix, width);
+                       iy = svm_image_texture_wrap_periodic(iy, height);
+                       iz = svm_image_texture_wrap_periodic(iz, depth);
+               }
+               else {
+                       if (extension == EXTENSION_CLIP) {
+                               if(x < 0.0f || y < 0.0f || z < 0.0f ||
+                                  x > 1.0f || y > 1.0f || z > 1.0f)
+                                       return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+                       }
+                       /* Fall through. */
+                       /* EXTENSION_EXTEND */
+                       ix = svm_image_texture_wrap_clamp(ix, width);
+                       iy = svm_image_texture_wrap_clamp(iy, height);
+                       iz = svm_image_texture_wrap_clamp(iz, depth);
+               }
+               r = svm_image_texture_read(kg, id, offset + ix + iy*width + iz*width*height);
+       }
+       else { /* INTERPOLATION_LINEAR */
+               float tx = svm_image_texture_frac(x*(float)width - 0.5f, &ix);
+               float ty = svm_image_texture_frac(y*(float)height - 0.5f, &iy);
+               float tz = svm_image_texture_frac(z*(float)depth - 0.5f, &iz);
+
+               if(extension == EXTENSION_REPEAT) {
+                       ix = svm_image_texture_wrap_periodic(ix, width);
+                       iy = svm_image_texture_wrap_periodic(iy, height);
+                       iz = svm_image_texture_wrap_periodic(iz, depth);
+
+                       nix = svm_image_texture_wrap_periodic(ix+1, width);
+                       niy = svm_image_texture_wrap_periodic(iy+1, height);
+                       niz = svm_image_texture_wrap_periodic(iz+1, depth);
+               }
+               else {
+                       if (extension == EXTENSION_CLIP)
+                               if(x < 0.0f || y < 0.0f || z < 0.0f ||
+                                  x > 1.0f || y > 1.0f || z > 1.0f)
+                                       return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+                       /* Fall through. */
+                       /*  EXTENSION_EXTEND */
+                       nix = svm_image_texture_wrap_clamp(ix+1, width);
+                       niy = svm_image_texture_wrap_clamp(iy+1, height);
+                       niz = svm_image_texture_wrap_clamp(iz+1, depth);
+
+                       ix = svm_image_texture_wrap_clamp(ix, width);
+                       iy = svm_image_texture_wrap_clamp(iy, height);
+                       iz = svm_image_texture_wrap_clamp(iz, depth);
+               }
+
+               r  = (1.0f - tz)*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + iy*width + iz*width*height);
+               r += (1.0f - tz)*(1.0f - ty)*tx*svm_image_texture_read(kg, id, offset + nix + iy*width + iz*width*height);
+               r += (1.0f - tz)*ty*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + niy*width + iz*width*height);
+               r += (1.0f - tz)*ty*tx*svm_image_texture_read(kg, id, offset + nix + niy*width + iz*width*height);
+
+               r += tz*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + iy*width + niz*width*height);
+               r += tz*(1.0f - ty)*tx*svm_image_texture_read(kg, id, offset + nix + iy*width + niz*width*height);
+               r += tz*ty*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + niy*width + niz*width*height);
+               r += tz*ty*tx*svm_image_texture_read(kg, id, offset + nix + niy*width + niz*width*height);
+
+       }
+
+       return r;
+}
index 37907cd8fdc1efcba2ac5fb95f128286df78b1e6..a68f97857b67916f56c7cee0f1709876a14f323b 100644 (file)
@@ -20,6 +20,7 @@
 #include "../../kernel_math.h"
 #include "../../kernel_types.h"
 #include "../../kernel_globals.h"
+#include "../../kernel_image_opencl.h"
 
 #include "../../kernel_film.h"
 
index 88d6dab04d08cb8aca925beb392e5a2b71c490f2..2135ee22b2e19d74abaef99da77c4a10fe3723f7 100644 (file)
@@ -21,6 +21,7 @@
 #include "kernel_math.h"
 #include "kernel_types.h"
 #include "kernel_globals.h"
+#include "kernel_image_opencl.h"
 
 #include "util_atomic.h"
 
index 378ce6501291ec9f08717d18d657b93d8d076783..9606064492e833eaa7eea2135cacc8053ce23852 100644 (file)
@@ -29,147 +29,6 @@ CCL_NAMESPACE_BEGIN
 #  define TEX_NUM_FLOAT4_IMAGES        TEX_NUM_FLOAT4_OPENCL
 #endif
 
-#ifdef __KERNEL_OPENCL__
-
-/* For OpenCL all images are packed in a single array, and we do manual lookup
- * and interpolation. */
-
-ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, int id, int offset)
-{
-       /* Float4 */
-       if(id < TEX_START_BYTE4_OPENCL) {
-               return kernel_tex_fetch(__tex_image_float4_packed, offset);
-       }
-       /* Byte4 */
-       else if(id < TEX_START_FLOAT_OPENCL) {
-               uchar4 r = kernel_tex_fetch(__tex_image_byte4_packed, offset);
-               float f = 1.0f/255.0f;
-               return make_float4(r.x*f, r.y*f, r.z*f, r.w*f);
-       }
-       /* Float */
-       else if(id < TEX_START_BYTE_OPENCL) {
-               float f = kernel_tex_fetch(__tex_image_float_packed, offset);
-               return make_float4(f, f, f, 1.0f);
-       }
-       /* Byte */
-       else {
-               uchar r = kernel_tex_fetch(__tex_image_byte_packed, offset);
-               float f = r * (1.0f/255.0f);
-               return make_float4(f, f, f, 1.0f);
-       }
-}
-
-ccl_device_inline int svm_image_texture_wrap_periodic(int x, int width)
-{
-       x %= width;
-       if(x < 0)
-               x += width;
-       return x;
-}
-
-ccl_device_inline int svm_image_texture_wrap_clamp(int x, int width)
-{
-       return clamp(x, 0, width-1);
-}
-
-ccl_device_inline float svm_image_texture_frac(float x, int *ix)
-{
-       int i = float_to_int(x) - ((x < 0.0f)? 1: 0);
-       *ix = i;
-       return x - (float)i;
-}
-
-ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb, uint use_alpha)
-{
-       uint4 info = kernel_tex_fetch(__tex_image_packed_info, id);
-       uint width = info.x;
-       uint height = info.y;
-       uint offset = info.z;
-
-       /* Image Options */
-       uint interpolation = (info.w & (1 << 0)) ? INTERPOLATION_CLOSEST : INTERPOLATION_LINEAR;
-       uint extension;
-       if(info.w & (1 << 1))
-               extension = EXTENSION_REPEAT;
-       else if(info.w & (1 << 2))
-               extension = EXTENSION_EXTEND;
-       else
-               extension = EXTENSION_CLIP;
-
-       float4 r;
-       int ix, iy, nix, niy;
-       if(interpolation == INTERPOLATION_CLOSEST) {
-               svm_image_texture_frac(x*width, &ix);
-               svm_image_texture_frac(y*height, &iy);
-
-               if(extension == EXTENSION_REPEAT) {
-                       ix = svm_image_texture_wrap_periodic(ix, width);
-                       iy = svm_image_texture_wrap_periodic(iy, height);
-               }
-               else if(extension == EXTENSION_CLIP) {
-                       if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f)
-                               return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-               }
-               else { /* EXTENSION_EXTEND */
-                       ix = svm_image_texture_wrap_clamp(ix, width);
-                       iy = svm_image_texture_wrap_clamp(iy, height);
-               }
-
-               r = svm_image_texture_read(kg, id, offset + ix + iy*width);
-       }
-       else { /* INTERPOLATION_LINEAR */
-               float tx = svm_image_texture_frac(x*width - 0.5f, &ix);
-               float ty = svm_image_texture_frac(y*height - 0.5f, &iy);
-
-               if(extension == EXTENSION_REPEAT) {
-                       ix = svm_image_texture_wrap_periodic(ix, width);
-                       iy = svm_image_texture_wrap_periodic(iy, height);
-
-                       nix = svm_image_texture_wrap_periodic(ix+1, width);
-                       niy = svm_image_texture_wrap_periodic(iy+1, height);
-               }
-               else {
-                       if(extension == EXTENSION_CLIP) {
-                               if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
-                                       return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-                               }
-                       }
-                       nix = svm_image_texture_wrap_clamp(ix+1, width);
-                       niy = svm_image_texture_wrap_clamp(iy+1, height);
-                       ix = svm_image_texture_wrap_clamp(ix, width);
-                       iy = svm_image_texture_wrap_clamp(iy, height);
-               }
-
-               r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + iy*width);
-               r += (1.0f - ty)*tx*svm_image_texture_read(kg, id, offset + nix + iy*width);
-               r += ty*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + niy*width);
-               r += ty*tx*svm_image_texture_read(kg, id, offset + nix + niy*width);
-       }
-
-       if(use_alpha && r.w != 1.0f && r.w != 0.0f) {
-               float invw = 1.0f/r.w;
-               r.x *= invw;
-               r.y *= invw;
-               r.z *= invw;
-
-               if(id >= TEX_NUM_FLOAT4_IMAGES) {
-                       r.x = min(r.x, 1.0f);
-                       r.y = min(r.y, 1.0f);
-                       r.z = min(r.z, 1.0f);
-               }
-       }
-
-       if(srgb) {
-               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);
-       }
-
-       return r;
-}
-
-#else
-
 ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb, uint use_alpha)
 {
 #ifdef __KERNEL_CPU__
@@ -180,6 +39,8 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
 #  else
        float4 r = kernel_tex_image_interp(id, x, y);
 #  endif
+#elif defined(__KERNEL_OPENCL__)
+       float4 r = kernel_tex_image_interp(kg, id, x, y);
 #else
        float4 r;
 
@@ -339,8 +200,6 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
        return r;
 }
 
-#endif
-
 /* Remap coordnate from 0..1 box to -1..-1 */
 ccl_device_inline float3 texco_remap_square(float3 co)
 {
index f54f4e8e888603fae8cf8e75486791d94f01f445..a8b3604a8a795e6c038a486ca0786eaa7cad06ae 100644 (file)
@@ -43,7 +43,7 @@ ccl_device void svm_node_tex_voxel(KernelGlobals *kg,
                co = transform_point(&tfm, co);
        }
        float4 r;
-#  if defined(__KERNEL_GPU__)
+#  if defined(__KERNEL_CUDA__)
 #    if __CUDA_ARCH__ >= 300
        CUtexObject tex = kernel_tex_fetch(__bindless_mapping, id);
        if(id < 2048) /* TODO(dingto): Make this a variable */
@@ -55,9 +55,11 @@ ccl_device void svm_node_tex_voxel(KernelGlobals *kg,
 #    else /* __CUDA_ARCH__ >= 300 */
        r = volume_image_texture_3d(id, co.x, co.y, co.z);
 #    endif
-#  else /* __KERNEL_GPU__ */
+#  elif defined(__KERNEL_OPENCL__)
+       r = kernel_tex_image_interp_3d(kg, id, co.x, co.y, co.z);
+#  else
        r = kernel_tex_image_interp_3d(id, co.x, co.y, co.z);
-#  endif
+#  endif /* __KERNEL_CUDA__ */
 #else
        float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
 #endif
index 7e24664b3febc2585492e8a29832de99e46b9c09..3cb0aa961ec5fff6177576758f2a0d6f3c0d932b 100644 (file)
@@ -1107,7 +1107,7 @@ void ImageManager::device_pack_images(Device *device,
 
        int info_size = tex_num_images[IMAGE_DATA_TYPE_FLOAT4] + tex_num_images[IMAGE_DATA_TYPE_BYTE4]
                        + tex_num_images[IMAGE_DATA_TYPE_FLOAT] + tex_num_images[IMAGE_DATA_TYPE_BYTE];
-       uint4 *info = dscene->tex_image_packed_info.resize(info_size);
+       uint4 *info = dscene->tex_image_packed_info.resize(info_size*2);
 
        /* Byte4 Textures*/
        type = IMAGE_DATA_TYPE_BYTE4;
@@ -1130,7 +1130,9 @@ void ImageManager::device_pack_images(Device *device,
 
                uint8_t options = pack_image_options(type, slot);
 
-               info[type_index_to_flattened_slot(slot, type)] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
+               int index = type_index_to_flattened_slot(slot, type) * 2;
+               info[index] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
+               info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0);
 
                memcpy(pixels_byte4+offset, (void*)tex_img.data_pointer, tex_img.memory_size());
                offset += tex_img.size();
@@ -1159,7 +1161,10 @@ void ImageManager::device_pack_images(Device *device,
                /* todo: support 3D textures, only CPU for now */
 
                uint8_t options = pack_image_options(type, slot);
-               info[type_index_to_flattened_slot(slot, type)] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
+
+               int index = type_index_to_flattened_slot(slot, type) * 2;
+               info[index] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
+               info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0);
 
                memcpy(pixels_float4+offset, (void*)tex_img.data_pointer, tex_img.memory_size());
                offset += tex_img.size();
@@ -1187,7 +1192,9 @@ void ImageManager::device_pack_images(Device *device,
 
                uint8_t options = pack_image_options(type, slot);
 
-               info[type_index_to_flattened_slot(slot, type)] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
+               int index = type_index_to_flattened_slot(slot, type) * 2;
+               info[index] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
+               info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0);
 
                memcpy(pixels_byte+offset, (void*)tex_img.data_pointer, tex_img.memory_size());
                offset += tex_img.size();
@@ -1216,7 +1223,10 @@ void ImageManager::device_pack_images(Device *device,
                /* todo: support 3D textures, only CPU for now */
 
                uint8_t options = pack_image_options(type, slot);
-               info[type_index_to_flattened_slot(slot, type)] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
+
+               int index = type_index_to_flattened_slot(slot, type) * 2;
+               info[index] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
+               info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0);
 
                memcpy(pixels_float+offset, (void*)tex_img.data_pointer, tex_img.memory_size());
                offset += tex_img.size();