const GLuint dims = get_texture_dims(stObj->base.Target);
GLuint level, lastLevel, width, height, depth;
GLuint bindings;
+ GLuint ptWidth, ptHeight, ptDepth, ptLayers;
enum pipe_format fmt;
DBG("%s\n", __FUNCTION__);
bindings = default_bindings(st, fmt);
+ st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
+ width, height, depth,
+ &ptWidth, &ptHeight, &ptDepth, &ptLayers);
+
stObj->pt = st_texture_create(st,
gl_target_to_pipe(stObj->base.Target),
fmt,
lastLevel,
- width,
- height,
- depth,
- 1,
+ ptWidth,
+ ptHeight,
+ ptDepth,
+ ptLayers,
bindings);
DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL));
GLuint face;
struct st_texture_image *firstImage;
enum pipe_format firstImageFormat;
+ GLuint ptWidth, ptHeight, ptDepth, ptLayers;
if (stObj->base._Complete) {
/* The texture is complete and we know exactly how many mipmap levels
/* Find gallium format for the Mesa texture */
firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat);
+ st_gl_texture_dims_to_pipe_dims(stObj->base.Target, stObj->width0,
+ stObj->height0, stObj->depth0,
+ &ptWidth, &ptHeight, &ptDepth, &ptLayers);
/* If we already have a gallium texture, check that it matches the texture
* object's format, target, size, num_levels, etc.
if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
!st_sampler_compat_formats(stObj->pt->format, firstImageFormat) ||
stObj->pt->last_level < stObj->lastLevel ||
- stObj->pt->width0 != stObj->width0 ||
- stObj->pt->height0 != stObj->height0 ||
- stObj->pt->depth0 != stObj->depth0)
+ stObj->pt->width0 != ptWidth ||
+ stObj->pt->height0 != ptHeight ||
+ stObj->pt->depth0 != ptDepth ||
+ stObj->pt->array_size != ptLayers)
{
/* The gallium texture does not match the Mesa texture so delete the
* gallium texture now. We'll make a new one below.
gl_target_to_pipe(stObj->base.Target),
firstImageFormat,
stObj->lastLevel,
- stObj->width0,
- stObj->height0,
- stObj->depth0,
- 1,
+ ptWidth,
+ ptHeight,
+ ptDepth,
+ ptLayers,
bindings);
if (!stObj->pt) {
assert(width0 > 0);
assert(height0 > 0);
assert(depth0 > 0);
+ if (target == PIPE_TEXTURE_CUBE)
+ assert(layers == 6);
DBG("%s target %s format %s last_level %d\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(target),
pt.width0 = width0;
pt.height0 = height0;
pt.depth0 = depth0;
- pt.array_size = (target == PIPE_TEXTURE_CUBE ? 6 : 1);
+ pt.array_size = (target == PIPE_TEXTURE_CUBE ? 6 : layers);
pt.usage = PIPE_USAGE_DEFAULT;
pt.bind = bind;
pt.flags = 0;
}
+/**
+ * In OpenGL the number of 1D array texture layers is the "height" and
+ * the number of 2D array texture layers is the "depth". In Gallium the
+ * number of layers in an array texture is a separate 'array_size' field.
+ * This function converts dimensions from the former to the later.
+ */
+void
+st_gl_texture_dims_to_pipe_dims(GLenum texture,
+ GLuint widthIn,
+ GLuint heightIn,
+ GLuint depthIn,
+ GLuint *widthOut,
+ GLuint *heightOut,
+ GLuint *depthOut,
+ GLuint *layersOut)
+{
+ switch (texture) {
+ case GL_TEXTURE_1D:
+ assert(heightIn == 1);
+ assert(depthIn == 1);
+ *widthOut = widthIn;
+ *heightOut = 1;
+ *depthOut = 1;
+ *layersOut = 1;
+ break;
+ case GL_TEXTURE_1D_ARRAY:
+ assert(depthIn == 1);
+ *widthOut = widthIn;
+ *heightOut = 1;
+ *depthOut = 1;
+ *layersOut = heightIn;
+ break;
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE:
+ assert(depthIn == 1);
+ *widthOut = widthIn;
+ *heightOut = heightIn;
+ *depthOut = 1;
+ *layersOut = 1;
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ assert(depthIn == 1);
+ *widthOut = widthIn;
+ *heightOut = heightIn;
+ *depthOut = 1;
+ *layersOut = 6;
+ break;
+ case GL_TEXTURE_2D_ARRAY:
+ *widthOut = widthIn;
+ *heightOut = heightIn;
+ *depthOut = 1;
+ *layersOut = depthIn;
+ break;
+ default:
+ assert(0 && "Unexpected texture in st_gl_texture_dims_to_pipe_dims()");
+ /* fall-through */
+ case GL_TEXTURE_3D:
+ *widthOut = widthIn;
+ *heightOut = heightIn;
+ *depthOut = depthIn;
+ *layersOut = 1;
+ break;
+ }
+}
+
+
/**
* Check if a texture image can be pulled into a unified mipmap texture.
*/
const struct gl_texture_image *image,
GLuint face, GLuint level)
{
+ GLuint ptWidth, ptHeight, ptDepth, ptLayers;
+
/* Images with borders are never pulled into mipmap textures.
*/
if (image->Border)
if (st_mesa_format_to_pipe_format(image->TexFormat) != pt->format)
return GL_FALSE;
+ st_gl_texture_dims_to_pipe_dims(image->TexObject->Target,
+ image->Width, image->Height, image->Depth,
+ &ptWidth, &ptHeight, &ptDepth, &ptLayers);
+
/* Test if this image's size matches what's expected in the
* established texture.
*/
- if (image->Width != u_minify(pt->width0, level) ||
- image->Height != u_minify(pt->height0, level) ||
- image->Depth != u_minify(pt->depth0, level))
+ if (ptWidth != u_minify(pt->width0, level) ||
+ ptHeight != u_minify(pt->height0, level) ||
+ ptDepth != u_minify(pt->depth0, level) ||
+ ptLayers != pt->array_size)
return GL_FALSE;
return GL_TRUE;
GLuint src_row_stride, GLuint src_image_stride)
{
struct pipe_context *pipe = st->pipe;
- GLuint depth = u_minify(dst->depth0, level);
GLuint i;
const GLubyte *srcUB = src;
struct pipe_transfer *dst_transfer;
+ GLuint layers;
+
+ if (dst->target == PIPE_TEXTURE_1D_ARRAY ||
+ dst->target == PIPE_TEXTURE_2D_ARRAY)
+ layers = dst->array_size;
+ else
+ layers = u_minify(dst->depth0, level);
DBG("%s\n", __FUNCTION__);
- for (i = 0; i < depth; i++) {
+ for (i = 0; i < layers; i++) {
dst_transfer = pipe_get_transfer(st->pipe, dst, level, face + i,
PIPE_TRANSFER_WRITE, 0, 0,
u_minify(dst->width0, level),