docs: function createTextureArray(gl, array) {
    var dtype = array.dtype
    var shape = array.shape.slice()
    var maxSize = gl.getParameter(gl.MAX_TEXTURE_SIZE)
    if(shape[0] < 0 || shape[0] > maxSize || shape[1] < 0 || shape[1] > maxSize) {
      throw new Error('gl-texture2d: Invalid texture size')
    }
    var packed = isPacked(shape, array.stride.slice())
    var type = 0
    if(dtype === 'float32') {
      type = gl.FLOAT
    } else if(dtype === 'float64') {
      type = gl.FLOAT
      packed = false
      dtype = 'float32'
    } else if(dtype === 'uint8') {
      type = gl.UNSIGNED_BYTE
    } else {
      type = gl.UNSIGNED_BYTE
      packed = false
      dtype = 'uint8'
    }
    var format = 0
    if(shape.length === 2) {
      format = gl.LUMINANCE
      shape = [shape[0], shape[1], 1]
      array = ndarray(array.data, shape, [array.stride[0], array.stride[1], 1], array.offset)
    } else if(shape.length === 3) {
      if(shape[2] === 1) {
        format = gl.ALPHA
      } else if(shape[2] === 2) {
        format = gl.LUMINANCE_ALPHA
      } else if(shape[2] === 3) {
        format = gl.RGB
      } else if(shape[2] === 4) {
        format = gl.RGBA
      } else {
        throw new Error('gl-texture2d: Invalid shape for pixel coords')
      }
    } else {
      throw new Error('gl-texture2d: Invalid shape for texture')
    }
    if(type === gl.FLOAT && !gl.getExtension('OES_texture_float')) {
      type = gl.UNSIGNED_BYTE
      packed = false
    }
    var buffer, buf_store
    var size = array.size
    if(!packed) {
      var stride = [shape[2], shape[2]*shape[0], 1]
      buf_store = pool.malloc(size, dtype)
      var buf_array = ndarray(buf_store, shape, stride, 0)
      if((dtype === 'float32' || dtype === 'float64') && type === gl.UNSIGNED_BYTE) {
        convertFloatToUint8(buf_array, array)
      } else {
        ops.assign(buf_array, array)
      }
      buffer = buf_store.subarray(0, size)
    } else if (array.offset === 0 && array.data.length === size) {
      buffer = array.data
    } else {
      buffer = array.data.subarray(array.offset, array.offset + size)
    }
    var tex = initTexture(gl)
    gl.texImage2D(gl.TEXTURE_2D, 0, format, shape[0], shape[1], 0, format, type, buffer)
    if(!packed) {
      pool.free(buf_store)
    }
    return new Texture2D(gl, tex, shape[0], shape[1], format, type)
  }