X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Ffreedreno%2Fa6xx%2Ffd6_blitter.c;h=4e4153ec718d59b0ea8e9c1e7e7cd0dca3c817bd;hb=d5c82c3c5f2f5e7a49630687173ff4f2debb3016;hp=d2a47f02bbacdc0f33ef6cadc95529edbfe5dd3e;hpb=bf0cf4c181f5b209e2af5dba05927157c0815cb7;p=mesa.git diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c index d2a47f02bba..4e4153ec718 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c @@ -148,9 +148,6 @@ ok_format(enum pipe_format pfmt) if (fmt == FMT6_NONE) return false; - if (fmt == FMT6_10_10_10_2_UNORM_DEST) - return false; - return true; } @@ -235,19 +232,59 @@ emit_setup(struct fd_batch *batch) OUT_RING(ring, fd6_context(batch->ctx)->magic.RB_CCU_CNTL_bypass); } -static uint32_t -blit_control(enum a6xx_format fmt, bool is_srgb) +static void +emit_blit_setup(struct fd_ringbuffer *ring, + enum pipe_format pfmt, bool scissor_enable, union pipe_color_union *color) { + enum a6xx_format fmt = fd6_pipe2color(pfmt); + bool is_srgb = util_format_is_srgb(pfmt); enum a6xx_2d_ifmt ifmt = fd6_ifmt(fmt); + OUT_PKT7(ring, CP_SET_MARKER, 1); + OUT_RING(ring, A6XX_CP_SET_MARKER_0_MODE(RM6_BLIT2DSCALE)); + if (is_srgb) { assert(ifmt == R2D_UNORM8); ifmt = R2D_UNORM8_SRGB; } - return A6XX_RB_2D_BLIT_CNTL_MASK(0xf) | + uint32_t blit_cntl = A6XX_RB_2D_BLIT_CNTL_MASK(0xf) | A6XX_RB_2D_BLIT_CNTL_COLOR_FORMAT(fmt) | - A6XX_RB_2D_BLIT_CNTL_IFMT(ifmt); + A6XX_RB_2D_BLIT_CNTL_IFMT(ifmt) | + COND(color, A6XX_RB_2D_BLIT_CNTL_SOLID_COLOR) | + COND(scissor_enable, A6XX_RB_2D_BLIT_CNTL_SCISSOR); + + OUT_PKT4(ring, REG_A6XX_RB_2D_BLIT_CNTL, 1); + OUT_RING(ring, blit_cntl); + + OUT_PKT4(ring, REG_A6XX_GRAS_2D_BLIT_CNTL, 1); + OUT_RING(ring, blit_cntl); + + if (fmt == FMT6_10_10_10_2_UNORM_DEST) + fmt = FMT6_16_16_16_16_FLOAT; + + /* This register is probably badly named... it seems that it's + * controlling the internal/accumulator format or something like + * that. It's certainly not tied to only the src format. + */ + OUT_PKT4(ring, REG_A6XX_SP_2D_SRC_FORMAT, 1); + OUT_RING(ring, A6XX_SP_2D_SRC_FORMAT_COLOR_FORMAT(fmt) | + COND(util_format_is_pure_sint(pfmt), + A6XX_SP_2D_SRC_FORMAT_SINT) | + COND(util_format_is_pure_uint(pfmt), + A6XX_SP_2D_SRC_FORMAT_UINT) | + COND(util_format_is_snorm(pfmt), + A6XX_SP_2D_SRC_FORMAT_SINT | + A6XX_SP_2D_SRC_FORMAT_NORM) | + COND(util_format_is_unorm(pfmt), +// TODO sometimes blob uses UINT+NORM but dEQP seems unhappy about that +// A6XX_SP_2D_SRC_FORMAT_UINT | + A6XX_SP_2D_SRC_FORMAT_NORM) | + COND(is_srgb, A6XX_SP_2D_SRC_FORMAT_SRGB) | + A6XX_SP_2D_SRC_FORMAT_MASK(0xf)); + + OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8C01, 1); + OUT_RING(ring, 0); } /* buffers need to be handled specially since x/width can exceed the bounds @@ -307,15 +344,7 @@ emit_blit_buffer(struct fd_context *ctx, struct fd_ringbuffer *ring, sshift = sbox->x & 0x3f; dshift = dbox->x & 0x3f; - OUT_PKT7(ring, CP_SET_MARKER, 1); - OUT_RING(ring, A6XX_CP_SET_MARKER_0_MODE(RM6_BLIT2DSCALE)); - - uint32_t blit_cntl = blit_control(FMT6_8_UNORM, false) | 0x20000000; - OUT_PKT4(ring, REG_A6XX_RB_2D_BLIT_CNTL, 1); - OUT_RING(ring, blit_cntl); - - OUT_PKT4(ring, REG_A6XX_GRAS_2D_BLIT_CNTL, 1); - OUT_RING(ring, blit_cntl); + emit_blit_setup(ring, PIPE_FORMAT_R8_UNORM, false, NULL); for (unsigned off = 0; off < sbox->width; off += (0x4000 - 0x40)) { unsigned soff, doff, w, p; @@ -380,12 +409,6 @@ emit_blit_buffer(struct fd_context *ctx, struct fd_ringbuffer *ring, OUT_RING(ring, 0x3f); OUT_WFI5(ring); - OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8C01, 1); - OUT_RING(ring, 0); - - OUT_PKT4(ring, REG_A6XX_SP_2D_SRC_FORMAT, 1); - OUT_RING(ring, 0xf180); - OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8E04, 1); OUT_RING(ring, fd6_context(ctx)->magic.RB_UNKNOWN_8E04_blit); @@ -400,16 +423,101 @@ emit_blit_buffer(struct fd_context *ctx, struct fd_ringbuffer *ring, } static void -emit_blit_or_clear_texture(struct fd_context *ctx, struct fd_ringbuffer *ring, - const struct pipe_blit_info *info, union pipe_color_union *color) +emit_blit_dst(struct fd_ringbuffer *ring, struct pipe_resource *prsc, enum pipe_format pfmt, unsigned level, unsigned layer) +{ + struct fd_resource *dst = fd_resource(prsc); + enum a6xx_format fmt = fd6_pipe2color(pfmt); + enum a6xx_tile_mode tile = fd_resource_tile_mode(prsc, level); + enum a3xx_color_swap swap = fd6_resource_swap(dst, pfmt); + uint32_t pitch = fd_resource_pitch(dst, level); + bool ubwc_enabled = fd_resource_ubwc_enabled(dst, level); + unsigned off = fd_resource_offset(dst, level, layer); + + if (fmt == FMT6_Z24_UNORM_S8_UINT) + fmt = FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8; + + OUT_PKT4(ring, REG_A6XX_RB_2D_DST_INFO, 9); + OUT_RING(ring, A6XX_RB_2D_DST_INFO_COLOR_FORMAT(fmt) | + A6XX_RB_2D_DST_INFO_TILE_MODE(tile) | + A6XX_RB_2D_DST_INFO_COLOR_SWAP(swap) | + COND(util_format_is_srgb(pfmt), A6XX_RB_2D_DST_INFO_SRGB) | + COND(ubwc_enabled, A6XX_RB_2D_DST_INFO_FLAGS)); + OUT_RELOC(ring, dst->bo, off, 0, 0); /* RB_2D_DST_LO/HI */ + OUT_RING(ring, A6XX_RB_2D_DST_SIZE_PITCH(pitch)); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + + if (ubwc_enabled) { + OUT_PKT4(ring, REG_A6XX_RB_2D_DST_FLAGS_LO, 6); + fd6_emit_flag_reference(ring, dst, level, layer); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + } +} + +static void +emit_blit_src(struct fd_ringbuffer *ring, const struct pipe_blit_info *info, unsigned layer, unsigned nr_samples) +{ + struct fd_resource *src = fd_resource(info->src.resource); + enum a6xx_format sfmt = fd6_pipe2color(info->src.format); + enum a6xx_tile_mode stile = fd_resource_tile_mode(info->src.resource, info->src.level); + enum a3xx_color_swap sswap = fd6_resource_swap(src, info->src.format); + uint32_t pitch = fd_resource_pitch(src, info->src.level); + bool subwc_enabled = fd_resource_ubwc_enabled(src, info->src.level); + unsigned soff = fd_resource_offset(src, info->src.level, layer); + uint32_t width = u_minify(src->base.width0, info->src.level) * nr_samples; + uint32_t height = u_minify(src->base.height0, info->src.level); + uint32_t filter = 0; + + if (info->filter == PIPE_TEX_FILTER_LINEAR) + filter = A6XX_SP_PS_2D_SRC_INFO_FILTER; + + enum a3xx_msaa_samples samples = fd_msaa_samples(src->base.nr_samples); + + if (sfmt == FMT6_10_10_10_2_UNORM_DEST) + sfmt = FMT6_10_10_10_2_UNORM; + + 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) | + A6XX_SP_PS_2D_SRC_INFO_SAMPLES(samples) | + COND(samples > MSAA_ONE && (info->mask & PIPE_MASK_RGBA), + A6XX_SP_PS_2D_SRC_INFO_SAMPLES_AVERAGE) | + COND(subwc_enabled, A6XX_SP_PS_2D_SRC_INFO_FLAGS) | + COND(util_format_is_srgb(info->src.format), A6XX_SP_PS_2D_SRC_INFO_SRGB) | + 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(pitch)); + + 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); + fd6_emit_flag_reference(ring, src, info->src.level, layer); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + } +} + +static void +emit_blit_texture(struct fd_context *ctx, + struct fd_ringbuffer *ring, const struct pipe_blit_info *info) { const struct pipe_box *sbox = &info->src.box; const struct pipe_box *dbox = &info->dst.box; - struct fd_resource *src, *dst; - uint32_t spitch, dpitch; - enum a6xx_format sfmt, dfmt; - enum a6xx_tile_mode stile, dtile; - enum a3xx_color_swap sswap, dswap; + struct fd_resource *dst; int sx1, sy1, sx2, sy2; int dx1, dy1, dx2, dy2; @@ -423,96 +531,29 @@ emit_blit_or_clear_texture(struct fd_context *ctx, struct fd_ringbuffer *ring, fprintf(stderr, "\n"); } - src = fd_resource(info->src.resource); dst = fd_resource(info->dst.resource); - spitch = fd_resource_pitch(src, info->src.level); - dpitch = fd_resource_pitch(dst, info->dst.level); - - sfmt = fd6_pipe2color(info->src.format); - dfmt = fd6_pipe2color(info->dst.format); - - stile = fd_resource_tile_mode(info->src.resource, info->src.level); - dtile = fd_resource_tile_mode(info->dst.resource, info->dst.level); - - /* Linear levels of a tiled resource are always WZYX, so look at - * rsc->tile_mode to determine the swap. - */ - sswap = fd6_resource_swap(src, info->src.format); - dswap = fd6_resource_swap(dst, info->dst.format); - uint32_t nr_samples = fd_resource_nr_samples(&dst->base); + sx1 = sbox->x * nr_samples; sy1 = sbox->y; sx2 = (sbox->x + sbox->width) * nr_samples - 1; sy2 = sbox->y + sbox->height - 1; + OUT_PKT4(ring, REG_A6XX_GRAS_2D_SRC_TL_X, 4); + OUT_RING(ring, A6XX_GRAS_2D_SRC_TL_X_X(sx1)); + OUT_RING(ring, A6XX_GRAS_2D_SRC_BR_X_X(sx2)); + OUT_RING(ring, A6XX_GRAS_2D_SRC_TL_Y_Y(sy1)); + OUT_RING(ring, A6XX_GRAS_2D_SRC_BR_Y_Y(sy2)); + dx1 = dbox->x * nr_samples; dy1 = dbox->y; dx2 = (dbox->x + dbox->width) * nr_samples - 1; dy2 = dbox->y + dbox->height - 1; - uint32_t width = u_minify(src->base.width0, info->src.level) * nr_samples; - uint32_t height = u_minify(src->base.height0, info->src.level); - - OUT_PKT7(ring, CP_SET_MARKER, 1); - OUT_RING(ring, A6XX_CP_SET_MARKER_0_MODE(RM6_BLIT2DSCALE)); - - uint32_t blit_cntl = blit_control(dfmt, util_format_is_srgb(info->dst.format)); - - if (color) { - blit_cntl |= A6XX_RB_2D_BLIT_CNTL_SOLID_COLOR; - - switch (info->dst.format) { - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24_UNORM_S8_UINT: - case PIPE_FORMAT_X24S8_UINT: { - uint32_t depth_unorm24 = color->f[0] * ((1u << 24) - 1); - uint8_t stencil = color->ui[1]; - color->ui[0] = depth_unorm24 & 0xff; - color->ui[1] = (depth_unorm24 >> 8) & 0xff; - color->ui[2] = (depth_unorm24 >> 16) & 0xff; - color->ui[3] = stencil; - - dfmt = FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8; - break; - } - default: - break; - } - - OUT_PKT4(ring, REG_A6XX_RB_2D_SRC_SOLID_C0, 4); - - switch (fd6_ifmt(dfmt)) { - case R2D_UNORM8: - case R2D_UNORM8_SRGB: - OUT_RING(ring, float_to_ubyte(color->f[0])); - OUT_RING(ring, float_to_ubyte(color->f[1])); - OUT_RING(ring, float_to_ubyte(color->f[2])); - OUT_RING(ring, float_to_ubyte(color->f[3])); - break; - case R2D_FLOAT16: - OUT_RING(ring, _mesa_float_to_half(color->f[0])); - OUT_RING(ring, _mesa_float_to_half(color->f[1])); - OUT_RING(ring, _mesa_float_to_half(color->f[2])); - OUT_RING(ring, _mesa_float_to_half(color->f[3])); - sfmt = FMT6_16_16_16_16_FLOAT; - break; - case R2D_FLOAT32: - case R2D_INT32: - case R2D_INT16: - case R2D_INT8: - default: - OUT_RING(ring, color->ui[0]); - OUT_RING(ring, color->ui[1]); - OUT_RING(ring, color->ui[2]); - OUT_RING(ring, color->ui[3]); - break; - } - } - - if (dtile != stile) - blit_cntl |= 0x20000000; + OUT_PKT4(ring, REG_A6XX_GRAS_2D_DST_TL, 2); + OUT_RING(ring, A6XX_GRAS_2D_DST_TL_X(dx1) | A6XX_GRAS_2D_DST_TL_Y(dy1)); + OUT_RING(ring, A6XX_GRAS_2D_DST_BR_X(dx2) | A6XX_GRAS_2D_DST_BR_Y(dy2)); if (info->scissor_enable) { OUT_PKT4(ring, REG_A6XX_GRAS_RESOLVE_CNTL_1, 2); @@ -520,130 +561,113 @@ emit_blit_or_clear_texture(struct fd_context *ctx, struct fd_ringbuffer *ring, A6XX_GRAS_RESOLVE_CNTL_1_Y(info->scissor.miny)); OUT_RING(ring, A6XX_GRAS_RESOLVE_CNTL_1_X(info->scissor.maxx - 1) | A6XX_GRAS_RESOLVE_CNTL_1_Y(info->scissor.maxy - 1)); - blit_cntl |= A6XX_RB_2D_BLIT_CNTL_SCISSOR; } - OUT_PKT4(ring, REG_A6XX_RB_2D_BLIT_CNTL, 1); - OUT_RING(ring, blit_cntl); - - OUT_PKT4(ring, REG_A6XX_GRAS_2D_BLIT_CNTL, 1); - OUT_RING(ring, blit_cntl); + emit_blit_setup(ring, info->dst.format, info->scissor_enable, NULL); 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); - bool subwc_enabled = fd_resource_ubwc_enabled(src, info->src.level); - bool dubwc_enabled = fd_resource_ubwc_enabled(dst, info->dst.level); + + emit_blit_src(ring, info, sbox->z + i, nr_samples); + emit_blit_dst(ring, info->dst.resource, info->dst.format, info->dst.level, dbox->z + i); /* - * Emit source: + * Blit command: */ - uint32_t filter = 0; - if (info->filter == PIPE_TEX_FILTER_LINEAR) - filter = A6XX_SP_PS_2D_SRC_INFO_FILTER; + OUT_PKT7(ring, CP_EVENT_WRITE, 1); + OUT_RING(ring, 0x3f); + OUT_WFI5(ring); - enum a3xx_msaa_samples samples = fd_msaa_samples(src->base.nr_samples); + OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8E04, 1); + OUT_RING(ring, fd6_context(ctx)->magic.RB_UNKNOWN_8E04_blit); - if (sfmt == FMT6_10_10_10_2_UNORM_DEST) - sfmt = FMT6_10_10_10_2_UNORM; + OUT_PKT7(ring, CP_BLIT, 1); + OUT_RING(ring, CP_BLIT_0_OP(BLIT_OP_SCALE)); - 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) | - A6XX_SP_PS_2D_SRC_INFO_SAMPLES(samples) | - COND(samples > MSAA_ONE && (info->mask & PIPE_MASK_RGBA), - A6XX_SP_PS_2D_SRC_INFO_SAMPLES_AVERAGE) | - COND(subwc_enabled, A6XX_SP_PS_2D_SRC_INFO_FLAGS) | - COND(util_format_is_srgb(info->src.format), A6XX_SP_PS_2D_SRC_INFO_SRGB) | - 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_WFI5(ring); - OUT_RING(ring, 0x00000000); - OUT_RING(ring, 0x00000000); - OUT_RING(ring, 0x00000000); - OUT_RING(ring, 0x00000000); - OUT_RING(ring, 0x00000000); + OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8E04, 1); + OUT_RING(ring, 0); /* RB_UNKNOWN_8E04 */ + } +} - if (subwc_enabled) { - OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_FLAGS_LO, 6); - fd6_emit_flag_reference(ring, src, info->src.level, sbox->z + i); - OUT_RING(ring, 0x00000000); - OUT_RING(ring, 0x00000000); - OUT_RING(ring, 0x00000000); - } +static void +emit_clear_color(struct fd_ringbuffer *ring, + enum pipe_format pfmt, union pipe_color_union *color) +{ + switch (pfmt) { + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_X24S8_UINT: { + uint32_t depth_unorm24 = color->f[0] * ((1u << 24) - 1); + uint8_t stencil = color->ui[1]; + color->ui[0] = depth_unorm24 & 0xff; + color->ui[1] = (depth_unorm24 >> 8) & 0xff; + color->ui[2] = (depth_unorm24 >> 16) & 0xff; + color->ui[3] = stencil; + break; + } + default: + break; + } - /* - * 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) | - COND(util_format_is_srgb(info->dst.format), A6XX_RB_2D_DST_INFO_SRGB) | - COND(dubwc_enabled, A6XX_RB_2D_DST_INFO_FLAGS)); - OUT_RELOC(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); - OUT_RING(ring, 0x00000000); + OUT_PKT4(ring, REG_A6XX_RB_2D_SRC_SOLID_C0, 4); + switch (fd6_ifmt(fd6_pipe2color(pfmt))) { + case R2D_UNORM8: + case R2D_UNORM8_SRGB: + OUT_RING(ring, float_to_ubyte(color->f[0])); + OUT_RING(ring, float_to_ubyte(color->f[1])); + OUT_RING(ring, float_to_ubyte(color->f[2])); + OUT_RING(ring, float_to_ubyte(color->f[3])); + break; + case R2D_FLOAT16: + OUT_RING(ring, _mesa_float_to_half(color->f[0])); + OUT_RING(ring, _mesa_float_to_half(color->f[1])); + OUT_RING(ring, _mesa_float_to_half(color->f[2])); + OUT_RING(ring, _mesa_float_to_half(color->f[3])); + break; + case R2D_FLOAT32: + case R2D_INT32: + case R2D_INT16: + case R2D_INT8: + default: + OUT_RING(ring, color->ui[0]); + OUT_RING(ring, color->ui[1]); + OUT_RING(ring, color->ui[2]); + OUT_RING(ring, color->ui[3]); + break; + } +} - if (dubwc_enabled) { - OUT_PKT4(ring, REG_A6XX_RB_2D_DST_FLAGS_LO, 6); - fd6_emit_flag_reference(ring, dst, info->dst.level, dbox->z + i); - OUT_RING(ring, 0x00000000); - OUT_RING(ring, 0x00000000); - OUT_RING(ring, 0x00000000); - } +void +fd6_clear_surface(struct fd_context *ctx, + struct fd_ringbuffer *ring, struct pipe_surface *psurf, + uint32_t width, uint32_t height, union pipe_color_union *color) +{ + if (DEBUG_BLIT) { + fprintf(stderr, "surface clear:\ndst resource: "); + util_dump_resource(stderr, psurf->texture); + fprintf(stderr, "\n"); + } + + uint32_t nr_samples = fd_resource_nr_samples(psurf->texture); + OUT_PKT4(ring, REG_A6XX_GRAS_2D_DST_TL, 2); + OUT_RING(ring, A6XX_GRAS_2D_DST_TL_X(0) | A6XX_GRAS_2D_DST_TL_Y(0)); + OUT_RING(ring, A6XX_GRAS_2D_DST_BR_X(width * nr_samples - 1) | + A6XX_GRAS_2D_DST_BR_Y(height - 1)); + + emit_clear_color(ring, psurf->format, color); + emit_blit_setup(ring, psurf->format, false, color); + + for (unsigned i = psurf->u.tex.first_layer; i <= psurf->u.tex.last_layer; i++) { + emit_blit_dst(ring, psurf->texture, psurf->format, psurf->u.tex.level, i); /* * Blit command: */ - OUT_PKT4(ring, REG_A6XX_GRAS_2D_SRC_TL_X, 4); - OUT_RING(ring, A6XX_GRAS_2D_SRC_TL_X_X(sx1)); - OUT_RING(ring, A6XX_GRAS_2D_SRC_BR_X_X(sx2)); - OUT_RING(ring, A6XX_GRAS_2D_SRC_TL_Y_Y(sy1)); - OUT_RING(ring, A6XX_GRAS_2D_SRC_BR_Y_Y(sy2)); - - OUT_PKT4(ring, REG_A6XX_GRAS_2D_DST_TL, 2); - OUT_RING(ring, A6XX_GRAS_2D_DST_TL_X(dx1) | A6XX_GRAS_2D_DST_TL_Y(dy1)); - OUT_RING(ring, A6XX_GRAS_2D_DST_BR_X(dx2) | A6XX_GRAS_2D_DST_BR_Y(dy2)); - OUT_PKT7(ring, CP_EVENT_WRITE, 1); OUT_RING(ring, 0x3f); OUT_WFI5(ring); - OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8C01, 1); - OUT_RING(ring, 0); - - if (dfmt == FMT6_10_10_10_2_UNORM_DEST) - sfmt = FMT6_16_16_16_16_FLOAT; - - /* This register is probably badly named... it seems that it's - * controlling the internal/accumulator format or something like - * that. It's certainly not tied to only the src format. - */ - 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) | - COND(util_format_is_srgb(info->dst.format), A6XX_SP_2D_SRC_FORMAT_SRGB) | - A6XX_SP_2D_SRC_FORMAT_MASK(0xf)); - OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8E04, 1); OUT_RING(ring, fd6_context(ctx)->magic.RB_UNKNOWN_8E04_blit); @@ -657,30 +681,6 @@ emit_blit_or_clear_texture(struct fd_context *ctx, struct fd_ringbuffer *ring, } } -void -fd6_clear_surface(struct fd_context *ctx, - struct fd_ringbuffer *ring, struct pipe_surface *psurf, - uint32_t width, uint32_t height, union pipe_color_union *color) -{ - struct pipe_blit_info info = {}; - - info.dst.resource = psurf->texture; - info.dst.level = psurf->u.tex.level; - info.dst.box.x = 0; - info.dst.box.y = 0; - info.dst.box.z = psurf->u.tex.first_layer; - info.dst.box.width = width; - info.dst.box.height = height; - info.dst.box.depth = psurf->u.tex.last_layer + 1 - psurf->u.tex.first_layer; - info.dst.format = psurf->format; - info.src = info.dst; - info.mask = util_format_get_mask(psurf->format); - info.filter = PIPE_TEX_FILTER_NEAREST; - info.scissor_enable = 0; - - emit_blit_or_clear_texture(ctx, ring, &info, color); -} - static bool handle_rgba_blit(struct fd_context *ctx, const struct pipe_blit_info *info) { @@ -727,7 +727,7 @@ handle_rgba_blit(struct fd_context *ctx, const struct pipe_blit_info *info) debug_assert(info->src.resource->target != PIPE_BUFFER); debug_assert(info->dst.resource->target != PIPE_BUFFER); fd_log(batch, "START BLIT (TEXTURE)"); - emit_blit_or_clear_texture(ctx, batch->draw, info, NULL); + emit_blit_texture(ctx, batch->draw, info); fd_log(batch, "END BLIT (TEXTURE)"); }