anchor.diff:      (copy-c-array-to-texture-backed-gpu-array c-a dst))
     dst)
   
  +(defn pack-pixels-from-texture ((tex-array gpu-array-t)
  +                                (pixel-format pixel-format)
  +                                row-alignment
  +                                pointer/offset)
  +    (values)
  +  (with-gpu-array-t tex-array
  +    (destructuring-bind (pix-format pix-type)
  +        (cepl.pixel-formats::compile-pixel-format pixel-format)
  +      (%with-scratch-texture-bound texture
  +        (setf (pack-alignment) row-alignment)
  +        (%gl:get-tex-image (foreign-enum-value '%gl:enum texture-type)
  +                           (coerce level-num 'real)
  +                           pix-format
  +                           pix-type
  +                           pointer/offset))))
  +  (values))
  +
   ;; [TODO] implement gl-fill and fill arguments
  -;; [TODO] Does not respect UNPACK_BUFFER
   (defn copy-texture-backed-gpu-array-to-new-c-array ((src gpu-array-t))
       c-array
  -  (with-gpu-array-t src
  -    (let* ((p-format (image-format->pixel-format
  -                      (gpu-array-t-image-format src)))
  -           (c-array (make-c-array nil :dimensions (gpu-array-dimensions src)
  -                                  :element-type p-format)))
  -      (destructuring-bind (format type)
  -          (cepl.pixel-formats::compile-pixel-format p-format)
  -        (%with-scratch-texture-bound texture
  -          (setf (pack-alignment) (c-array-row-alignment c-array))
  -          (%gl:get-tex-image (foreign-enum-value '%gl:enum texture-type)
  -                             (coerce level-num 'real)
  -                             format
  -                             type
  -                             (pointer c-array))))
  -      c-array)))
  +  (let* ((p-format (image-format->pixel-format
  +                    (gpu-array-t-image-format src)))
  +         (c-array (make-c-array nil
  +                                :dimensions (gpu-array-dimensions src)
  +                                :element-type p-format
  +                                :row-alignment 1)))
  +    (setf (gpu-buffer-bound (cepl-context) :pixel-pack-buffer) nil)
  +    (pack-pixels-from-texture src p-format 1 (c-array-pointer c-array))
  +    c-array))
  +
  +(defn copy-texture-backed-gpu-array-to-c-array ((src gpu-array-t)
  +                                                (dst c-array))
  +    c-array
  +  ;; {TODO} loosen up the type requirement. Pixel transfers can do a bunch
  +  ;;        of transforms
  +  (check-array-types-for-copy (image-format->lisp-type
  +                               (gpu-array-t-image-format src))
  +                              (c-array-element-type dst))
  +  (check-array-sizes-for-copy (gpu-array-dimensions src)
  +                              (c-array-dimensions dst))
  +  (let ((pixel-format (lisp-type->pixel-format dst)))
  +    (setf (gpu-buffer-bound (cepl-context) :pixel-pack-buffer) nil)
  +    (pack-pixels-from-texture src
  +                              pixel-format
  +                              (c-array-row-alignment dst)
  +                              (c-array-pointer dst)))
  +  dst)
  +
  +(defn copy-texture-backed-gpu-array-to-new-buffer-backed-gpu-array
  +    ((src gpu-array-t))
  +    gpu-array-bb
  +  (let* ((p-format (image-format->pixel-format
  +                    (gpu-array-t-image-format src)))
  +         (gpu-array-bb (make-gpu-array nil
  +                                  :dimensions (gpu-array-dimensions src)
  +                                  :element-type p-format
  +                                  :row-alignment 1)))
  +    (setf (gpu-buffer-bound (cepl-context) :pixel-pack-buffer)
  +          (gpu-array-bb-buffer gpu-array-bb))
  +    (pack-pixels-from-texture
  +     src
  +     p-format
  +     1
  +     (gpu-array-bb-offset-in-bytes-into-buffer gpu-array-bb))
  +    gpu-array-bb))
  +
  +(defn copy-texture-backed-gpu-array-to-buffer-backed-gpu-array
  +    ((src gpu-array-t)
  +     (dst gpu-array-bb))
  +    gpu-array-bb
  +  ;; {TODO} loosen up the type requirement. Pixel transfers can do a bunch
  +  ;;        of transforms
  +  (check-array-types-for-copy (image-format->lisp-type
  +                               (gpu-array-t-image-format src))
  +                              (gpu-array-bb-element-type dst))
  +  (check-array-sizes-for-copy (gpu-array-dimensions src)
  +                              (gpu-array-dimensions dst))
  +  (let ((pixel-format (lisp-type->pixel-format dst)))
  +    (setf (gpu-buffer-bound (cepl-context) :pixel-pack-buffer)
  +          (gpu-array-bb-buffer dst))
  +    (pack-pixels-from-texture src
  +                              pixel-format
  +                              (gpu-array-bb-row-alignment dst)
  +                              (gpu-array-bb-offset-in-bytes-into-buffer dst)))
  +  dst)
   
   (defn copy-texture-backed-gpu-array-to-new-lisp-data ((src gpu-array-t))
       t
  
positive.code:       (t (error "not currently supported for upload: ~a" tex-type)))))
  
  
  
  (defun+ upload-from-buffer-to-gpu-array-t (&rest args)
    (declare (ignore args))
    (error "upload-from-buffer-to-gpu-array-t is not implemented yet"))
  
  ;;------------------------------------------------------------
  
  (define-const +valid-texture-storage-options+
  
negative.code:   (typecase initial-contents
      (null (error 'make-tex-no-content-no-type))
      (c-array (lisp-type->image-format
                (c-array-element-type initial-contents)))
      (gpu-array-bb (lisp-type->image-format
                     (gpu-array-bb-element-type initial-contents)))
      (uploadable-lisp-seq (lisp-type->image-format
                            (cepl.c-arrays::lisp->gl-type
                             (cepl.c-arrays::scan-for-type initial-contents))))))
  