ok_format(enum pipe_format pfmt)
{
enum a6xx_color_fmt fmt = fd6_pipe2color(pfmt);
+
+ switch (pfmt) {
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z16_UNORM:
+ case PIPE_FORMAT_Z32_UNORM:
+ case PIPE_FORMAT_Z32_FLOAT:
+ case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+ case PIPE_FORMAT_S8_UINT:
+ return true;
+ default:
+ break;
+ }
+
if (fmt == ~0)
return false;
*/
fail_if(info->dst.box.depth != info->src.box.depth);
- /* We can blit if both or neither formats are compressed formats... */
- fail_if(util_format_is_compressed(info->src.format) !=
- util_format_is_compressed(info->src.format));
-
/* Fail if unsupported format: */
fail_if(!ok_format(info->src.format));
fail_if(!ok_format(info->dst.format));
+ /* We can blit if both or neither formats are compressed formats... */
+ fail_if(util_format_is_compressed(info->src.format) !=
+ util_format_is_compressed(info->src.format));
+
/* ... but only if they're the same compression format. */
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));
-
fail_if(!ok_dims(info->src.resource, &info->src.box, info->src.level));
fail_if(!ok_dims(info->dst.resource, &info->dst.box, info->dst.level));
debug_assert(info->dst.box.height >= 0);
debug_assert(info->dst.box.depth >= 0);
- fail_if(info->dst.resource->nr_samples + info->src.resource->nr_samples > 2);
+ /* We could probably blit between resources with equal sample count.. */
+ fail_if(info->dst.resource->nr_samples > 1);
+
+ /* CP_BLIT supports resolving, but seems to pick one only of the samples
+ * (no blending). This doesn't work for RGBA resolves, so we fall back in
+ * that case. However, GL/GLES spec says:
+ *
+ * "If the source formats are integer types or stencil values, a single
+ * sample’s value is selected for each pixel. If the source formats are
+ * floating-point or normalized types, the sample values for each pixel
+ * are resolved in an implementationdependent manner. If the source
+ * formats are depth values, sample values are resolved in an
+ * implementation-dependent manner where the result will be between the
+ * minimum and maximum depth values in the pixel."
+ *
+ * so do those with CP_BLIT.
+ *
+ * TODO since we re-write z/s blits to RGBA, we'll fail this check in some
+ * cases where we don't need to.
+ */
+ fail_if((info->mask & PIPE_MASK_RGBA) &&
+ info->src.resource->nr_samples > 1);
fail_if(info->window_rectangle_include);
- fail_if(info->render_condition_enable);
+ fail_if(util_format_is_srgb(info->src.format));
+ fail_if(util_format_is_srgb(info->dst.format));
+
+ const struct util_format_description *src_desc =
+ util_format_description(info->src.format);
+ const struct util_format_description *dst_desc =
+ util_format_description(info->dst.format);
+ const int common_channels = MIN2(src_desc->nr_channels, dst_desc->nr_channels);
+
+ if (info->mask & PIPE_MASK_RGBA) {
+ for (int i = 0; i < common_channels; i++) {
+ fail_if(memcmp(&src_desc->channel[i],
+ &dst_desc->channel[i],
+ sizeof(src_desc->channel[0])));
+ }
+ }
fail_if(info->alpha_blend);
- fail_if(info->mask != util_format_get_mask(info->src.format));
-
- fail_if(info->mask != util_format_get_mask(info->dst.format));
-
return true;
}
static void
-emit_setup(struct fd_ringbuffer *ring)
+emit_setup(struct fd_batch *batch)
{
- OUT_PKT7(ring, CP_EVENT_WRITE, 1);
- OUT_RING(ring, PC_CCU_INVALIDATE_COLOR);
-
- OUT_PKT7(ring, CP_EVENT_WRITE, 1);
- OUT_RING(ring, LRZ_FLUSH);
-
- OUT_PKT7(ring, CP_SKIP_IB2_ENABLE_GLOBAL, 1);
- OUT_RING(ring, 0x0);
-
- OUT_WFI5(ring);
+ struct fd_ringbuffer *ring = batch->draw;
- OUT_PKT4(ring, REG_A6XX_RB_CCU_CNTL, 1);
- OUT_RING(ring, 0x10000000);
+ fd6_event_write(batch, ring, 0x1d, true);
+ fd6_event_write(batch, ring, FACENESS_FLUSH, true);
+ fd6_event_write(batch, ring, PC_CCU_INVALIDATE_COLOR, false);
+ fd6_event_write(batch, ring, PC_CCU_INVALIDATE_DEPTH, false);
}
static uint32_t
dshift = dbox->x & 0x3f;
OUT_PKT7(ring, CP_SET_MARKER, 1);
- OUT_RING(ring, A2XX_CP_SET_MARKER_0_MODE(RM6_BLIT2DSCALE));
+ OUT_RING(ring, A6XX_CP_SET_MARKER_0_MODE(RM6_BLIT2DSCALE));
uint32_t blit_cntl = blit_control(RB6_R8_UNORM) | 0x20000000;
OUT_PKT4(ring, REG_A6XX_RB_2D_BLIT_CNTL, 1);
/*
* Emit source:
*/
- OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_INFO, 13);
+ OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_INFO, 10);
OUT_RING(ring, A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT(RB6_R8_UNORM) |
A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(TILE6_LINEAR) |
- A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(WZYX) | 0x500000);
+ A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(WZYX) |
+ 0x500000);
OUT_RING(ring, A6XX_SP_PS_2D_SRC_SIZE_WIDTH(sshift + w) |
A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(1)); /* SP_PS_2D_SRC_SIZE */
OUT_RELOC(ring, src->bo, soff, 0, 0); /* SP_PS_2D_SRC_LO/HI */
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
-
/*
* Emit destination:
*/
OUT_RING(ring, A6XX_RB_2D_DST_INFO_COLOR_FORMAT(RB6_R8_UNORM) |
A6XX_RB_2D_DST_INFO_TILE_MODE(TILE6_LINEAR) |
A6XX_RB_2D_DST_INFO_COLOR_SWAP(WZYX));
- OUT_RELOC(ring, dst->bo, doff, 0, 0); /* RB_2D_DST_LO/HI */
+ OUT_RELOCW(ring, dst->bo, doff, 0, 0); /* RB_2D_DST_LO/HI */
OUT_RING(ring, A6XX_RB_2D_DST_SIZE_PITCH(p));
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x3f);
OUT_WFI5(ring);
- OUT_PKT4(ring, 0x8c01, 1);
+ OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8C01, 1);
OUT_RING(ring, 0);
- OUT_PKT4(ring, 0xacc0, 1);
+ OUT_PKT4(ring, REG_A6XX_SP_2D_SRC_FORMAT, 1);
OUT_RING(ring, 0xf180);
- OUT_PKT4(ring, 0x8e04, 1);
+ OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8E04, 1);
OUT_RING(ring, 0x01000000);
OUT_PKT7(ring, CP_BLIT, 1);
OUT_WFI5(ring);
- OUT_PKT4(ring, 0x8e04, 1);
+ OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8E04, 1);
OUT_RING(ring, 0);
}
}
enum a6xx_tile_mode stile, dtile;
enum a3xx_color_swap sswap, dswap;
unsigned spitch, dpitch;
- unsigned sx1, sy1, sx2, sy2;
- unsigned dx1, dy1, dx2, dy2;
+ int sx1, sy1, sx2, sy2;
+ int dx1, dy1, dx2, dy2;
if (DEBUG_BLIT_FALLBACK) {
fprintf(stderr, "texture blit: ");
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));
+ OUT_RING(ring, A6XX_CP_SET_MARKER_0_MODE(RM6_BLIT2DSCALE));
uint32_t blit_cntl = blit_control(dfmt);
for (unsigned i = 0; i < info->dst.box.depth; i++) {
unsigned soff = fd_resource_offset(src, info->src.level, sbox->z + i);
unsigned doff = fd_resource_offset(dst, info->dst.level, dbox->z + i);
+ unsigned subwcoff = fd_resource_ubwc_offset(src, info->src.level, sbox->z + i);
+ unsigned dubwcoff = fd_resource_ubwc_offset(dst, info->dst.level, dbox->z + i);
+ bool subwc_enabled = fd_resource_ubwc_enabled(src, info->src.level);
+ bool dubwc_enabled = fd_resource_ubwc_enabled(dst, info->dst.level);
/*
* Emit source:
if (info->filter == PIPE_TEX_FILTER_LINEAR)
filter = A6XX_SP_PS_2D_SRC_INFO_FILTER;
- OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_INFO, 13);
+ enum a3xx_msaa_samples samples = fd_msaa_samples(src->base.nr_samples);
+
+ OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_INFO, 10);
OUT_RING(ring, A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT(sfmt) |
A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(stile) |
- A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(sswap) | 0x500000 | filter);
+ A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(sswap) |
+ A6XX_SP_PS_2D_SRC_INFO_SAMPLES(samples) |
+ COND(subwc_enabled, A6XX_SP_PS_2D_SRC_INFO_FLAGS) |
+ 0x500000 | filter);
OUT_RING(ring, A6XX_SP_PS_2D_SRC_SIZE_WIDTH(width) |
A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(height)); /* SP_PS_2D_SRC_SIZE */
OUT_RELOC(ring, src->bo, soff, 0, 0); /* SP_PS_2D_SRC_LO/HI */
OUT_RING(ring, A6XX_SP_PS_2D_SRC_PITCH_PITCH(spitch));
+
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
+ if (subwc_enabled) {
+ OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_FLAGS_LO, 6);
+ OUT_RELOC(ring, src->bo, subwcoff, 0, 0);
+ OUT_RING(ring, A6XX_SP_PS_2D_SRC_FLAGS_PITCH_PITCH(src->ubwc_pitch) |
+ A6XX_SP_PS_2D_SRC_FLAGS_PITCH_ARRAY_PITCH(src->ubwc_size));
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ }
/*
* Emit destination:
OUT_PKT4(ring, REG_A6XX_RB_2D_DST_INFO, 9);
OUT_RING(ring, A6XX_RB_2D_DST_INFO_COLOR_FORMAT(dfmt) |
A6XX_RB_2D_DST_INFO_TILE_MODE(dtile) |
- A6XX_RB_2D_DST_INFO_COLOR_SWAP(dswap));
- OUT_RELOC(ring, dst->bo, doff, 0, 0); /* RB_2D_DST_LO/HI */
+ A6XX_RB_2D_DST_INFO_COLOR_SWAP(dswap) |
+ COND(dubwc_enabled, A6XX_RB_2D_DST_INFO_FLAGS));
+ OUT_RELOCW(ring, dst->bo, doff, 0, 0); /* RB_2D_DST_LO/HI */
OUT_RING(ring, A6XX_RB_2D_DST_SIZE_PITCH(dpitch));
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
+ if (dubwc_enabled) {
+ OUT_PKT4(ring, REG_A6XX_RB_2D_DST_FLAGS_LO, 6);
+ OUT_RELOCW(ring, dst->bo, dubwcoff, 0, 0);
+ OUT_RING(ring, A6XX_RB_2D_DST_FLAGS_PITCH_PITCH(dst->ubwc_pitch) |
+ A6XX_RB_2D_DST_FLAGS_PITCH_ARRAY_PITCH(dst->ubwc_size));
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ }
+
/*
* Blit command:
*/
OUT_RING(ring, 0x3f);
OUT_WFI5(ring);
- OUT_PKT4(ring, 0x8c01, 1);
+ OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8C01, 1);
OUT_RING(ring, 0);
- OUT_PKT4(ring, 0xacc0, 1);
- OUT_RING(ring, 0xf180);
-
- OUT_PKT4(ring, 0x8e04, 1);
+ OUT_PKT4(ring, REG_A6XX_SP_2D_SRC_FORMAT, 1);
+ OUT_RING(ring, A6XX_SP_2D_SRC_FORMAT_COLOR_FORMAT(sfmt) |
+ COND(util_format_is_pure_sint(info->src.format),
+ A6XX_SP_2D_SRC_FORMAT_SINT) |
+ COND(util_format_is_pure_uint(info->src.format),
+ A6XX_SP_2D_SRC_FORMAT_UINT) |
+ COND(util_format_is_snorm(info->src.format),
+ A6XX_SP_2D_SRC_FORMAT_SINT |
+ A6XX_SP_2D_SRC_FORMAT_NORM) |
+ COND(util_format_is_unorm(info->src.format),
+// TODO sometimes blob uses UINT+NORM but dEQP seems unhappy about that
+// A6XX_SP_2D_SRC_FORMAT_UINT |
+ A6XX_SP_2D_SRC_FORMAT_NORM) |
+ 0xf000);
+
+ OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8E04, 1);
OUT_RING(ring, 0x01000000);
OUT_PKT7(ring, CP_BLIT, 1);
OUT_WFI5(ring);
- OUT_PKT4(ring, 0x8e04, 1);
+ OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8E04, 1);
OUT_RING(ring, 0);
}
}
-static void
-fd6_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
+static bool handle_rgba_blit(struct fd_context *ctx, const struct pipe_blit_info *info);
+
+/**
+ * Re-written z/s blits can still fail for various reasons (for example MSAA).
+ * But we want to do the fallback blit with the re-written pipe_blit_info,
+ * in particular as u_blitter cannot blit stencil. So handle the fallback
+ * ourself and never "fail".
+ */
+static bool
+do_rewritten_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
{
- struct fd_context *ctx = fd_context(pctx);
- struct fd_batch *batch;
+ bool success = handle_rgba_blit(ctx, info);
+ if (!success)
+ success = fd_blitter_blit(ctx, info);
+ debug_assert(success); /* fallback should never fail! */
+ return success;
+}
- if (!can_do_blit(info)) {
- fd_blitter_pipe_begin(ctx, info->render_condition_enable, false, FD_STAGE_BLIT);
- fd_blitter_blit(ctx, info);
- fd_blitter_pipe_end(ctx);
- return;
+/**
+ * Handle depth/stencil blits either via u_blitter and/or re-writing the
+ * blit into an equivilant format that we can handle
+ */
+static bool
+handle_zs_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
+{
+ struct pipe_blit_info blit = *info;
+
+ if (DEBUG_BLIT_FALLBACK) {
+ fprintf(stderr, "---- handle_zs_blit: ");
+ util_dump_blit_info(stderr, info);
+ fprintf(stderr, "\ndst resource: ");
+ util_dump_resource(stderr, info->dst.resource);
+ fprintf(stderr, "\nsrc resource: ");
+ util_dump_resource(stderr, info->src.resource);
+ fprintf(stderr, "\n");
}
- fd_fence_ref(pctx->screen, &ctx->last_fence, NULL);
+ switch (info->dst.format) {
+ case PIPE_FORMAT_S8_UINT:
+ debug_assert(info->mask == PIPE_MASK_S);
+ blit.mask = PIPE_MASK_R;
+ blit.src.format = PIPE_FORMAT_R8_UINT;
+ blit.dst.format = PIPE_FORMAT_R8_UINT;
+ return do_rewritten_blit(ctx, &blit);
+
+ case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+ if (info->mask & PIPE_MASK_Z) {
+ blit.mask = PIPE_MASK_R;
+ blit.src.format = PIPE_FORMAT_R32_FLOAT;
+ blit.dst.format = PIPE_FORMAT_R32_FLOAT;
+ do_rewritten_blit(ctx, &blit);
+ }
+
+ if (info->mask & PIPE_MASK_S) {
+ blit.mask = PIPE_MASK_R;
+ blit.src.format = PIPE_FORMAT_R8_UINT;
+ blit.dst.format = PIPE_FORMAT_R8_UINT;
+ blit.src.resource = &fd_resource(info->src.resource)->stencil->base;
+ blit.dst.resource = &fd_resource(info->dst.resource)->stencil->base;
+ do_rewritten_blit(ctx, &blit);
+ }
+
+ return true;
+
+ case PIPE_FORMAT_Z16_UNORM:
+ blit.mask = PIPE_MASK_R;
+ blit.src.format = PIPE_FORMAT_R16_UNORM;
+ blit.dst.format = PIPE_FORMAT_R16_UNORM;
+ return do_rewritten_blit(ctx, &blit);
+
+ case PIPE_FORMAT_Z32_UNORM:
+ case PIPE_FORMAT_Z32_FLOAT:
+ debug_assert(info->mask == PIPE_MASK_Z);
+ blit.mask = PIPE_MASK_R;
+ blit.src.format = PIPE_FORMAT_R32_UINT;
+ blit.dst.format = PIPE_FORMAT_R32_UINT;
+ return do_rewritten_blit(ctx, &blit);
+
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ blit.mask = 0;
+ if (info->mask & PIPE_MASK_Z)
+ blit.mask |= PIPE_MASK_R | PIPE_MASK_G | PIPE_MASK_B;
+ if (info->mask & PIPE_MASK_S)
+ blit.mask |= PIPE_MASK_A;
+ blit.src.format = PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8;
+ blit.dst.format = PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8;
+ return fd_blitter_blit(ctx, &blit);
+
+ default:
+ return false;
+ }
+}
+
+static bool
+handle_rgba_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
+{
+ struct fd_batch *batch;
+
+ debug_assert(!(info->mask & PIPE_MASK_ZS));
+
+ if (!can_do_blit(info))
+ return false;
+
+ fd_fence_ref(&ctx->last_fence, NULL);
batch = fd_bc_alloc_batch(&ctx->screen->batch_cache, ctx, true);
mtx_unlock(&ctx->screen->lock);
- emit_setup(batch->draw);
+ emit_setup(batch);
if ((info->src.resource->target == PIPE_BUFFER) &&
(info->dst.resource->target == PIPE_BUFFER)) {
fd6_event_write(batch, batch->draw, 0x1d, true);
fd6_event_write(batch, batch->draw, FACENESS_FLUSH, true);
fd6_event_write(batch, batch->draw, CACHE_FLUSH_TS, true);
+ fd6_cache_inv(batch, batch->draw);
fd_resource(info->dst.resource)->valid = true;
batch->needs_flush = true;
- fd_batch_flush(batch, false, false);
+ fd_batch_flush(batch, false);
fd_batch_reference(&batch, NULL);
+
+ return true;
}
-static void
-fd6_resource_copy_region(struct pipe_context *pctx,
- struct pipe_resource *dst,
- unsigned dst_level,
- unsigned dstx, unsigned dsty, unsigned dstz,
- struct pipe_resource *src,
- unsigned src_level,
- const struct pipe_box *src_box)
+static bool
+fd6_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
{
- struct pipe_blit_info info;
-
- debug_assert(src->format == dst->format);
-
- memset(&info, 0, sizeof info);
- info.dst.resource = dst;
- info.dst.level = dst_level;
- info.dst.box.x = dstx;
- info.dst.box.y = dsty;
- info.dst.box.z = dstz;
- info.dst.box.width = src_box->width;
- info.dst.box.height = src_box->height;
- assert(info.dst.box.width >= 0);
- assert(info.dst.box.height >= 0);
- info.dst.box.depth = 1;
- info.dst.format = dst->format;
- info.src.resource = src;
- info.src.level = src_level;
- info.src.box = *src_box;
- info.src.format = src->format;
- info.mask = util_format_get_mask(src->format);
- info.filter = PIPE_TEX_FILTER_NEAREST;
- info.scissor_enable = 0;
-
- fd6_blit(pctx, &info);
+ if (info->mask & PIPE_MASK_ZS)
+ return handle_zs_blit(ctx, info);
+ return handle_rgba_blit(ctx, info);
}
void
if (fd_mesa_debug & FD_DBG_NOBLIT)
return;
- pctx->resource_copy_region = fd6_resource_copy_region;
- pctx->blit = fd6_blit;
+ fd_context(pctx)->blit = fd6_blit;
}
unsigned
fd6_tile_mode(const struct pipe_resource *tmpl)
{
+ /* if the mipmap level 0 is still too small to be tiled, then don't
+ * bother pretending:
+ */
+ if (fd_resource_level_linear(tmpl, 0))
+ return TILE6_LINEAR;
+
/* 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;
}