fail_if(util_format_is_compressed(info->src.format) &&
info->src.format != info->dst.format);
- /* hw ignores {SRC,DST}_INFO.COLOR_SWAP if {SRC,DST}_INFO.TILE_MODE
- * is set (not linear). We can kind of get around that when tiling/
- * untiling by setting both src and dst COLOR_SWAP=WZYX, but that
- * means the formats must match:
- */
- fail_if((fd_resource(info->dst.resource)->tile_mode ||
- fd_resource(info->src.resource)->tile_mode) &&
- info->dst.format != info->src.format);
-
/* src box can be inverted, which we don't support.. dst box cannot: */
fail_if((info->src.box.width < 0) || (info->src.box.height < 0));
dtile = fd_resource_level_linear(info->dst.resource, info->dst.level) ?
TILE6_LINEAR : dst->tile_mode;
- sswap = fd6_pipe2swap(info->src.format);
- dswap = fd6_pipe2swap(info->dst.format);
+ sswap = stile ? WZYX : fd6_pipe2swap(info->src.format);
+ dswap = dtile ? WZYX : fd6_pipe2swap(info->dst.format);
if (util_format_is_compressed(info->src.format)) {
debug_assert(info->src.format == info->dst.format);
uint32_t width = DIV_ROUND_UP(u_minify(src->base.width0, info->src.level), blockwidth) * nelements;
uint32_t height = DIV_ROUND_UP(u_minify(src->base.height0, info->src.level), blockheight);
- /* if dtile, then dswap ignored by hw, and likewise if stile then sswap
- * ignored by hw.. but in this case we have already rejected the blit
- * if src and dst formats differ, so juse use WZYX for both src and
- * dst swap mode (so we don't change component order)
- */
- if (stile || dtile) {
- debug_assert(info->src.format == info->dst.format);
- sswap = dswap = WZYX;
- }
-
OUT_PKT7(ring, CP_SET_MARKER, 1);
OUT_RING(ring, A2XX_CP_SET_MARKER_0_MODE(RM6_BLIT2DSCALE));
/* basically just has to be a format we can blit, so uploads/downloads
* via linear staging buffer works:
*/
- return TILE6_3;
+ if (ok_format(tmpl->format))
+ return TILE6_3;
+
+ return TILE6_LINEAR;
}
#include "util/u_format.h"
#include "fd6_format.h"
+#include "freedreno_resource.h"
/* Specifies the table of all the formats and their features. Also supplies
}
}
-static inline enum a6xx_tex_swiz
-tex_swiz(unsigned swiz)
+enum a6xx_tex_swiz
+fd6_pipe2swiz(unsigned swiz)
{
switch (swiz) {
default:
}
uint32_t
-fd6_tex_swiz(enum pipe_format format, unsigned swizzle_r, unsigned swizzle_g,
+fd6_tex_swiz(struct pipe_resource *prsc, unsigned swizzle_r, unsigned swizzle_g,
unsigned swizzle_b, unsigned swizzle_a)
{
const struct util_format_description *desc =
- util_format_description(format);
+ util_format_description(prsc->format);
unsigned char swiz[4] = {
swizzle_r, swizzle_g, swizzle_b, swizzle_a,
- }, rswiz[4];
+ }, rswiz[4], *swizp;
util_format_compose_swizzles(desc->swizzle, swiz, rswiz);
- return A6XX_TEX_CONST_0_SWIZ_X(tex_swiz(rswiz[0])) |
- A6XX_TEX_CONST_0_SWIZ_Y(tex_swiz(rswiz[1])) |
- A6XX_TEX_CONST_0_SWIZ_Z(tex_swiz(rswiz[2])) |
- A6XX_TEX_CONST_0_SWIZ_W(tex_swiz(rswiz[3]));
+ if (fd_resource(prsc)->tile_mode) {
+ /* for tiled modes, we don't get SWAP, so manually apply that
+ * extra step of swizzle:
+ */
+ enum a3xx_color_swap swap = fd6_pipe2swap(prsc->format);
+ unsigned char swapswiz[][4] = {
+ [WZYX] = { 0, 1, 2, 3 },
+ [WXYZ] = { 2, 1, 0, 3 },
+ [ZYXW] = { 3, 0, 1, 2 },
+ [XYZW] = { 3, 2, 1, 0 },
+ };
+
+ util_format_compose_swizzles(swapswiz[swap], rswiz, swiz);
+ swizp = swiz;
+ } else {
+ swizp = rswiz;
+ }
+
+ return A6XX_TEX_CONST_0_SWIZ_X(fd6_pipe2swiz(swizp[0])) |
+ A6XX_TEX_CONST_0_SWIZ_Y(fd6_pipe2swiz(swizp[1])) |
+ A6XX_TEX_CONST_0_SWIZ_Z(fd6_pipe2swiz(swizp[2])) |
+ A6XX_TEX_CONST_0_SWIZ_W(fd6_pipe2swiz(swizp[3]));
}
enum a3xx_color_swap fd6_pipe2swap(enum pipe_format format);
enum a6xx_tex_fetchsize fd6_pipe2fetchsize(enum pipe_format format);
enum a6xx_depth_format fd6_pipe2depth(enum pipe_format format);
+enum a6xx_tex_swiz fd6_pipe2swiz(unsigned swiz);
-uint32_t fd6_tex_swiz(enum pipe_format format, unsigned swizzle_r,
+uint32_t fd6_tex_swiz(struct pipe_resource *prsc, unsigned swizzle_r,
unsigned swizzle_g, unsigned swizzle_b, unsigned swizzle_a);
static inline enum a6xx_2d_ifmt
struct fd_resource_slice *slice = NULL;
uint32_t stride = 0;
uint32_t offset = 0;
+ uint32_t tile_mode;
if (!pfb->cbufs[i])
continue;
uint32_t base = gmem ? gmem->cbuf_base[i] : 0;
slice = fd_resource_slice(rsc, psurf->u.tex.level);
format = fd6_pipe2color(pformat);
- swap = fd6_pipe2swap(pformat);
sint = util_format_is_pure_sint(pformat);
uint = util_format_is_pure_uint(pformat);
psurf->u.tex.first_layer);
stride = slice->pitch * rsc->cpp * pfb->samples;
+ swap = rsc->tile_mode ? WZYX : fd6_pipe2swap(pformat);
+
+ if (rsc->tile_mode &&
+ fd_resource_level_linear(psurf->texture, psurf->u.tex.level))
+ tile_mode = TILE6_LINEAR;
+ else
+ tile_mode = rsc->tile_mode;
debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
debug_assert((offset + slice->size0) <= fd_bo_size(rsc->bo));
OUT_PKT4(ring, REG_A6XX_RB_MRT_BUF_INFO(i), 6);
OUT_RING(ring, A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format) |
- A6XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(rsc->tile_mode) |
+ A6XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) |
A6XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap));
OUT_RING(ring, A6XX_RB_MRT_PITCH(stride));
OUT_RING(ring, A6XX_RB_MRT_ARRAY_PITCH(slice->size0));
enum a6xx_color_fmt format = fd6_pipe2color(pfmt);
uint32_t stride = slice->pitch * rsc->cpp;
uint32_t size = slice->size0;
- enum a3xx_color_swap swap = fd6_pipe2swap(pfmt);
+ enum a3xx_color_swap swap = rsc->tile_mode ? WZYX : fd6_pipe2swap(pfmt);
enum a3xx_msaa_samples samples =
fd_msaa_samples(rsc->base.nr_samples);
+ uint32_t tile_mode;
- // TODO: tile mode
- // bool tiled;
- // tiled = rsc->tile_mode &&
- // !fd_resource_level_linear(&rsc->base, psurf->u.tex.level);
+ if (rsc->tile_mode &&
+ fd_resource_level_linear(&rsc->base, psurf->u.tex.level))
+ tile_mode = TILE6_LINEAR;
+ else
+ tile_mode = rsc->tile_mode;
OUT_PKT4(ring, REG_A6XX_RB_BLIT_DST_INFO, 5);
OUT_RING(ring,
- A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR) |
+ A6XX_RB_BLIT_DST_INFO_TILE_MODE(tile_mode) |
A6XX_RB_BLIT_DST_INFO_SAMPLES(samples) |
A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format) |
A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(swap));
};
struct fd6_image {
+ struct pipe_resource *prsc;
enum pipe_format pfmt;
enum a6xx_tex_fmt fmt;
enum a6xx_tex_fetchsize fetchsize;
return;
}
+ img->prsc = prsc;
img->pfmt = format;
img->fmt = fd6_pipe2tex(format);
img->fetchsize = fd6_pipe2fetchsize(format);
OUT_RING(ring, CP_LOAD_STATE6_2_EXT_SRC_ADDR_HI(0));
OUT_RING(ring, A6XX_TEX_CONST_0_FMT(img->fmt) |
- fd6_tex_swiz(img->pfmt, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y,
+ fd6_tex_swiz(img->prsc, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y,
PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W) |
COND(img->srgb, A6XX_TEX_CONST_0_SRGB));
OUT_RING(ring, A6XX_TEX_CONST_1_WIDTH(img->width) |
#include "util/u_format.h"
#include "fd6_screen.h"
+#include "fd6_blitter.h"
#include "fd6_context.h"
#include "fd6_format.h"
#include "fd6_resource.h"
pscreen->is_format_supported = fd6_screen_is_format_supported;
screen->setup_slices = fd6_setup_slices;
+ screen->tile_mode = fd6_tile_mode;
}
so->texconst0 =
A6XX_TEX_CONST_0_FMT(fd6_pipe2tex(format)) |
A6XX_TEX_CONST_0_SAMPLES(fd_msaa_samples(prsc->nr_samples)) |
- fd6_tex_swiz(format, cso->swizzle_r, cso->swizzle_g,
+ fd6_tex_swiz(prsc, cso->swizzle_r, cso->swizzle_g,
cso->swizzle_b, cso->swizzle_a);
/* NOTE: since we sample z24s8 using 8888_UINT format, the swizzle
* Note that gallium expects stencil sampler to return (s,s,s,s)
* which isn't quite true. To make that happen we'd have to massage
* the swizzle. But in practice only the .x component is used.
+ *
+ * Skip this in the tile case because tiled formats are not swapped
+ * and we have already applied the inverse swap in fd6_tex_swiz()
+ * to componsate for that.
*/
- if (format == PIPE_FORMAT_X24S8_UINT) {
+ if ((format == PIPE_FORMAT_X24S8_UINT) && !rsc->tile_mode) {
so->texconst0 |= A6XX_TEX_CONST_0_SWAP(XYZW);
}