mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-19 09:18:10 +02:00
I am not aware of any legal reason why this should be there and I haven't done it on any new code in ages. Drop it rather than updating the emails. I am quite sure people know how to reach me in any case. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenz.ca> Acked-by: Mary Guillemard <mary@mary.zone> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40031>
164 lines
6.1 KiB
C
164 lines
6.1 KiB
C
/*
|
|
* Copyright (c) 2011-2013 Luc Verhaegen <libv@skynet.be>
|
|
* Copyright (c) 2018 Alyssa Rosenzweig
|
|
* Copyright (c) 2018 Vasily Khoruzhick <anarsoul@gmail.com>
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#ifndef H_PANFROST_TILING
|
|
#define H_PANFROST_TILING
|
|
|
|
#include <stdint.h>
|
|
#include "util/bitscan.h"
|
|
#include <util/format/u_format.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* The depth and stencil aspects of a Z24_UNORM_S8_UINT image are interleaved,
|
|
* where the bottom 24 bits are depth and the top 8 bits are stencil. When
|
|
* copying to/from a Z24S8 tiled image, the pan_interleave_zs enum specifies
|
|
* whether to (de)interleave the depth/stencil aspects */
|
|
enum pan_interleave_zs {
|
|
/* Copy all aspects, no interleaving */
|
|
PAN_INTERLEAVE_NONE,
|
|
/* Copy only the depth aspect of a Z24S8 tiled image to/from linear Z24X8 */
|
|
PAN_INTERLEAVE_DEPTH,
|
|
/* Copy only the stencil aspect of a Z24S8 tiled image to/from linear S8 */
|
|
PAN_INTERLEAVE_STENCIL,
|
|
};
|
|
|
|
/**
|
|
* Get the appropriate pan_interleave_zs mode for copying to/from a given
|
|
* format.
|
|
*
|
|
* @depth Whether to copy the depth aspect
|
|
* @stencil Whether to copy the stencil aspect
|
|
*/
|
|
enum pan_interleave_zs
|
|
pan_get_interleave_zs(enum pipe_format format, bool depth, bool stencil);
|
|
|
|
/**
|
|
* Load a rectangular region from a tiled image to a linear staging image.
|
|
*
|
|
* @dst Linear destination
|
|
* @src Tiled source
|
|
* @x Region of interest of source in pixels, aligned to block size
|
|
* @y Region of interest of source in pixels, aligned to block size
|
|
* @w Region of interest of source in pixels, aligned to block size
|
|
* @h Region of interest of source in pixels, aligned to block size
|
|
* @dst_stride Stride in bytes of linear destination
|
|
* @src_stride Number of bytes between adjacent rows of tiles in source.
|
|
* @format Format of the source and destination image
|
|
* @interleave How to deinterleave ZS aspects from the tiled image
|
|
*/
|
|
void pan_load_tiled_image(void *dst, const void *src, unsigned x, unsigned y,
|
|
unsigned w, unsigned h, uint32_t dst_stride,
|
|
uint32_t src_stride, enum pipe_format format,
|
|
enum pan_interleave_zs interleave);
|
|
|
|
/**
|
|
* Store a linear staging image to a rectangular region of a tiled image.
|
|
*
|
|
* @dst Tiled destination
|
|
* @src Linear source
|
|
* @x Region of interest of destination in pixels, aligned to block size
|
|
* @y Region of interest of destination in pixels, aligned to block size
|
|
* @w Region of interest of destination in pixels, aligned to block size
|
|
* @h Region of interest of destination in pixels, aligned to block size
|
|
* @dst_stride Number of bytes between adjacent rows of tiles in destination.
|
|
* @src_stride Stride in bytes of linear source
|
|
* @format Format of the source and destination image
|
|
* @interleave How to interleave a ZS aspects to the tiled image
|
|
*/
|
|
void pan_store_tiled_image(void *dst, const void *src, unsigned x, unsigned y,
|
|
unsigned w, unsigned h, uint32_t dst_stride,
|
|
uint32_t src_stride, enum pipe_format format,
|
|
enum pan_interleave_zs interleave);
|
|
|
|
/**
|
|
* Copy a rectangular region from one tiled image to another.
|
|
*
|
|
* @dst Tiled destination
|
|
* @src Tiled source
|
|
* @dst_x Region of interest of destination in pixels, aligned to block size
|
|
* @dst_y Region of interest of destination in pixels, aligned to block size
|
|
* @src_x Region of interest of source in pixels, aligned to block size
|
|
* @src_y Region of interest of source in pixels, aligned to block size
|
|
* @w Size of region of interest in pixels, aligned to block size
|
|
* @h Size of region of interest in pixels, aligned to block size
|
|
* @dst_stride Number of bytes between adjacent rows of tiles in destination.
|
|
* @src_stride Number of bytes between adjacent rows of tiles in source.
|
|
* @format Format of the source and destination image
|
|
*/
|
|
void pan_copy_tiled_image(void *dst, const void *src, unsigned dst_x,
|
|
unsigned dst_y, unsigned src_x, unsigned src_y,
|
|
unsigned w, unsigned h, uint32_t dst_stride,
|
|
uint32_t src_stride, enum pipe_format format);
|
|
|
|
static inline
|
|
void *assume_pixel_aligned(void *ptr, const unsigned pixel_size)
|
|
{
|
|
if (pixel_size == 1)
|
|
return __builtin_assume_aligned(ptr, 1);
|
|
else if (pixel_size == 2)
|
|
return __builtin_assume_aligned(ptr, 2);
|
|
else if (pixel_size == 4)
|
|
return __builtin_assume_aligned(ptr, 4);
|
|
else if (pixel_size == 8)
|
|
return __builtin_assume_aligned(ptr, 8);
|
|
else if (pixel_size == 16)
|
|
return __builtin_assume_aligned(ptr, 16);
|
|
else
|
|
UNREACHABLE("unexpected pixel size");
|
|
}
|
|
|
|
static inline
|
|
void pan_access_image_pixel(void *dst, void *src, const unsigned pixel_size,
|
|
enum pan_interleave_zs interleave, bool is_store)
|
|
{
|
|
if (util_is_power_of_two_nonzero(pixel_size)) {
|
|
src = assume_pixel_aligned(src, pixel_size);
|
|
if (interleave != PAN_INTERLEAVE_STENCIL)
|
|
dst = assume_pixel_aligned(dst, pixel_size);
|
|
}
|
|
|
|
switch (interleave) {
|
|
case PAN_INTERLEAVE_NONE:
|
|
if (is_store)
|
|
memcpy(dst, src, pixel_size);
|
|
else
|
|
memcpy(src, dst, pixel_size);
|
|
break;
|
|
case PAN_INTERLEAVE_DEPTH:
|
|
/* interleave only applies to Z24S8 */
|
|
assert(pixel_size == 4);
|
|
if (is_store) {
|
|
uint32_t src_pixel = *(uint32_t *) src;
|
|
*(uint16_t *) dst = src_pixel & 0xffff;
|
|
*((uint8_t *) dst + 2) = (src_pixel >> 16) & 0xff;
|
|
} else {
|
|
/* The top 8 bits of Z24X8 are unused, so we can overwrite them
|
|
* with zeros in a single 32B write, instead of needing separate
|
|
* 16B and 8B writes */
|
|
*(uint32_t *) src = *(uint32_t *) dst & 0xffffff;
|
|
}
|
|
break;
|
|
case PAN_INTERLEAVE_STENCIL:
|
|
/* interleave only applies to Z24S8 */
|
|
assert(pixel_size == 4);
|
|
if (is_store)
|
|
*((uint8_t *) dst + 3) = *(uint8_t *) src;
|
|
else
|
|
*(uint8_t *) src = *((uint8_t *) dst + 3);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef __cplusplus
|
|
} /* extern C */
|
|
#endif
|
|
|
|
#endif
|