}
uint32_t blit_cntl = A6XX_RB_2D_BLIT_CNTL_ROTATE(blt->rotation) |
+ COND(blt->type == TU_BLIT_CLEAR, A6XX_RB_2D_BLIT_CNTL_SOLID_COLOR) |
A6XX_RB_2D_BLIT_CNTL_COLOR_FORMAT(fmt) | /* not required? */
COND(fmt == RB6_Z24_UNORM_S8_UINT_AS_R8G8B8A8, A6XX_RB_2D_BLIT_CNTL_D24S8) |
A6XX_RB_2D_BLIT_CNTL_MASK(0xf) |
/*
* Emit source:
*/
- tu_cs_emit_pkt4(cs, REG_A6XX_SP_PS_2D_SRC_INFO, 10);
- tu_cs_emit(cs, blit_image_info(&blt->src, true, blt->stencil_read) |
- A6XX_SP_PS_2D_SRC_INFO_SAMPLES(tu_msaa_samples(blt->src.samples)) |
- /* TODO: should disable this bit for integer formats ? */
- COND(blt->src.samples > 1, A6XX_SP_PS_2D_SRC_INFO_SAMPLES_AVERAGE) |
- COND(blt->filter, A6XX_SP_PS_2D_SRC_INFO_FILTER) |
- 0x500000);
- tu_cs_emit(cs, A6XX_SP_PS_2D_SRC_SIZE_WIDTH(blt->src.x + blt->src.width) |
- A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(blt->src.y + blt->src.height));
- tu_cs_emit_qw(cs, blt->src.va);
- tu_cs_emit(cs, A6XX_SP_PS_2D_SRC_PITCH_PITCH(blt->src.pitch));
-
- tu_cs_emit(cs, 0x00000000);
- tu_cs_emit(cs, 0x00000000);
- tu_cs_emit(cs, 0x00000000);
- tu_cs_emit(cs, 0x00000000);
- tu_cs_emit(cs, 0x00000000);
+ if (blt->type == TU_BLIT_CLEAR) {
+ tu_cs_emit_pkt4(cs, REG_A6XX_RB_2D_SRC_SOLID_C0, 4);
+ tu_cs_emit(cs, blt->clear_value[0]);
+ tu_cs_emit(cs, blt->clear_value[1]);
+ tu_cs_emit(cs, blt->clear_value[2]);
+ tu_cs_emit(cs, blt->clear_value[3]);
+ } else {
+ tu_cs_emit_pkt4(cs, REG_A6XX_SP_PS_2D_SRC_INFO, 10);
+ tu_cs_emit(cs, blit_image_info(&blt->src, true, blt->stencil_read) |
+ A6XX_SP_PS_2D_SRC_INFO_SAMPLES(tu_msaa_samples(blt->src.samples)) |
+ /* TODO: should disable this bit for integer formats ? */
+ COND(blt->src.samples > 1, A6XX_SP_PS_2D_SRC_INFO_SAMPLES_AVERAGE) |
+ COND(blt->filter, A6XX_SP_PS_2D_SRC_INFO_FILTER) |
+ 0x500000);
+ tu_cs_emit(cs, A6XX_SP_PS_2D_SRC_SIZE_WIDTH(blt->src.x + blt->src.width) |
+ A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(blt->src.y + blt->src.height));
+ tu_cs_emit_qw(cs, blt->src.va);
+ tu_cs_emit(cs, A6XX_SP_PS_2D_SRC_PITCH_PITCH(blt->src.pitch));
+
+ tu_cs_emit(cs, 0x00000000);
+ tu_cs_emit(cs, 0x00000000);
+ tu_cs_emit(cs, 0x00000000);
+ tu_cs_emit(cs, 0x00000000);
+ tu_cs_emit(cs, 0x00000000);
+ }
/*
* Emit destination:
tu_cs_emit(cs, 0);
}
-void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt, bool copy)
+void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt)
{
- if (copy) {
+ switch (blt->type) {
+ case TU_BLIT_COPY:
blt->stencil_read =
blt->dst.fmt == VK_FORMAT_R8_UINT &&
blt->src.fmt == VK_FORMAT_D24_UNORM_S8_UINT;
blt->dst.width *= blt->dst.samples;
blt->src.samples = 1;
blt->dst.samples = 1;
- } else {
+ break;
+ case TU_BLIT_CLEAR:
+ /* unsupported format cleared as UINT32 */
+ if (blt->dst.fmt == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
+ blt->dst.fmt = blt->src.fmt = VK_FORMAT_R32_UINT;
+ assert(blt->dst.samples == 1); /* TODO */
+ break;
+ default:
assert(blt->dst.samples == 1);
}
for (unsigned layer = 0; layer < blt->layers; layer++) {
if ((blt->src.va & 63) || (blt->src.pitch & 63)) {
/* per line copy path (buffer_to_image) */
- assert(copy && !blt->src.tiled);
+ assert(blt->type == TU_BLIT_COPY && !blt->src.tiled);
struct tu_blit line_blt = *blt;
uint64_t src_va = line_blt.src.va + blt->src.pitch * blt->src.y;
}
} else if ((blt->dst.va & 63) || (blt->dst.pitch & 63)) {
/* per line copy path (image_to_buffer) */
- assert(copy && !blt->dst.tiled);
+ assert(blt->type == TU_BLIT_COPY && !blt->dst.tiled);
struct tu_blit line_blt = *blt;
uint64_t dst_va = line_blt.dst.va + blt->dst.pitch * blt->dst.y;
}
static inline struct tu_blit_surf
-tu_blit_surf_whole(struct tu_image *image)
+tu_blit_surf_whole(struct tu_image *image, int level, int layer)
{
- return tu_blit_surf(image, (VkImageSubresourceLayers){}, (VkOffset3D[]) {
- {}, {image->extent.width, image->extent.height}
+ return tu_blit_surf(image, (VkImageSubresourceLayers){
+ .mipLevel = level,
+ .baseArrayLayer = layer,
+ }, (VkOffset3D[]) {
+ {}, {
+ u_minify(image->extent.width, level),
+ u_minify(image->extent.height, level),
+ }
});
}
+enum tu_blit_type {
+ TU_BLIT_DEFAULT,
+ TU_BLIT_COPY,
+ TU_BLIT_CLEAR,
+};
+
struct tu_blit {
struct tu_blit_surf dst;
struct tu_blit_surf src;
bool filter;
bool stencil_read;
enum a6xx_rotation rotation;
+ uint32_t clear_value[4];
+ enum tu_blit_type type;
};
-void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt, bool copy);
+void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt);
#endif /* TU_BLIT_H */
tu_bo_list_add(&cmd->bo_list, dst_img->bo, MSM_SUBMIT_BO_WRITE);
tu_blit(cmd, &(struct tu_blit) {
- .dst = tu_blit_surf_whole(dst_img),
- .src = tu_blit_surf_whole(src_img),
+ .dst = tu_blit_surf_whole(dst_img, 0, 0),
+ .src = tu_blit_surf_whole(src_img, 0, 0),
.layers = 1,
- }, false);
+ });
}
}
}
}
+void
+tu_2d_clear_color(const VkClearColorValue *val, VkFormat format, uint32_t buf[4])
+{
+ const struct vk_format_description *desc = vk_format_description(format);
+
+ /* not supported by 2D engine, cleared as U32 */
+ if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
+ buf[0] = float3_to_rgb9e5(val->float32);
+ return;
+ }
+
+ enum a6xx_2d_ifmt ifmt = tu6_rb_fmt_to_ifmt(tu6_get_native_format(format)->rb);
+
+ assert(desc && desc->layout == VK_FORMAT_LAYOUT_PLAIN);
+
+ for (unsigned i = 0; i < desc->nr_channels; i++) {
+ const struct vk_format_channel_description *ch = &desc->channel[i];
+
+ switch (ifmt) {
+ case R2D_INT32:
+ case R2D_INT16:
+ case R2D_INT8:
+ case R2D_FLOAT32:
+ buf[i] = val->uint32[i];
+ break;
+ case R2D_FLOAT16:
+ buf[i] = util_float_to_half(val->float32[i]);
+ break;
+ case R2D_UNORM8: {
+ float linear = val->float32[i];
+ if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB && i < 3)
+ linear = util_format_linear_to_srgb_float(val->float32[i]);
+
+ if (ch->type == VK_FORMAT_TYPE_SIGNED)
+ buf[i] = tu_pack_float32_for_snorm(linear, 8);
+ else
+ buf[i] = tu_pack_float32_for_unorm(linear, 8);
+ } break;
+ default:
+ unreachable("unexpected ifmt");
+ break;
+ }
+ }
+}
+
+void
+tu_2d_clear_zs(const VkClearDepthStencilValue *val, VkFormat format, uint32_t buf[4])
+{
+ switch (format) {
+ case VK_FORMAT_X8_D24_UNORM_PACK32:
+ case VK_FORMAT_D24_UNORM_S8_UINT:
+ buf[0] = tu_pack_float32_for_unorm(val->depth, 24);
+ buf[1] = buf[0] >> 8;
+ buf[2] = buf[0] >> 16;
+ buf[3] = val->stencil;
+ return;
+ case VK_FORMAT_D16_UNORM:
+ case VK_FORMAT_D32_SFLOAT:
+ buf[0] = fui(val->depth);
+ return;
+ case VK_FORMAT_S8_UINT:
+ buf[0] = val->stencil;
+ return;
+ default:
+ unreachable("unexpected zs format");
+ break;
+ }
+}
+
static void
tu_physical_device_get_format_properties(
struct tu_physical_device *physical_device,
.rotation = rotate[mirror_y][mirror_x],
};
- tu_blit(cmdbuf, &blt, false);
+ tu_blit(cmdbuf, &blt);
}
void
*/
#include "tu_private.h"
+#include "tu_blit.h"
+
+static void
+clear_image(struct tu_cmd_buffer *cmdbuf,
+ struct tu_image *image,
+ uint32_t clear_value[4],
+ const VkImageSubresourceRange *range)
+{
+ uint32_t level_count = tu_get_levelCount(image, range);
+ uint32_t layer_count = tu_get_layerCount(image, range);
+
+ if (image->type == VK_IMAGE_TYPE_3D) {
+ assert(layer_count == 1);
+ assert(range->baseArrayLayer == 0);
+ }
+
+ for (unsigned j = 0; j < level_count; j++) {
+ if (image->type == VK_IMAGE_TYPE_3D)
+ layer_count = u_minify(image->extent.depth, range->baseMipLevel + j);
+
+ tu_blit(cmdbuf, &(struct tu_blit) {
+ .dst = tu_blit_surf_whole(image, range->baseMipLevel + j, range->baseArrayLayer),
+ .src = tu_blit_surf_whole(image, range->baseMipLevel + j, range->baseArrayLayer),
+ .layers = layer_count,
+ .clear_value = {clear_value[0], clear_value[1], clear_value[2], clear_value[3]},
+ .type = TU_BLIT_CLEAR,
+ });
+ }
+}
void
tu_CmdClearColorImage(VkCommandBuffer commandBuffer,
uint32_t rangeCount,
const VkImageSubresourceRange *pRanges)
{
+ TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
+ TU_FROM_HANDLE(tu_image, image, image_h);
+ uint32_t clear_value[4] = {};
+
+ tu_2d_clear_color(pColor, image->vk_format, clear_value);
+
+ tu_bo_list_add(&cmdbuf->bo_list, image->bo, MSM_SUBMIT_BO_WRITE);
+
+ for (unsigned i = 0; i < rangeCount; i++)
+ clear_image(cmdbuf, image, clear_value, pRanges + i);
}
void
uint32_t rangeCount,
const VkImageSubresourceRange *pRanges)
{
+ TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
+ TU_FROM_HANDLE(tu_image, image, image_h);
+ uint32_t clear_value[4] = {};
+
+ tu_2d_clear_zs(pDepthStencil, image->vk_format, clear_value);
+
+ tu_bo_list_add(&cmdbuf->bo_list, image->bo, MSM_SUBMIT_BO_WRITE);
+
+ for (unsigned i = 0; i < rangeCount; i++)
+ clear_image(cmdbuf, image, clear_value, pRanges + i);
}
void
uint32_t rectCount,
const VkClearRect *pRects)
{
+ tu_finishme("CmdClearAttachments");
}
.dst = tu_blit_surf_ext(dst_image, info->imageSubresource, info->imageOffset, info->imageExtent),
.src = tu_blit_buffer(src_buffer, dst_image->vk_format, info),
.layers = MAX2(info->imageExtent.depth, info->imageSubresource.layerCount),
- }, true);
+ .type = TU_BLIT_COPY,
+ });
}
static void
.dst = tu_blit_buffer(dst_buffer, src_image->vk_format, info),
.src = tu_blit_surf_ext(src_image, info->imageSubresource, info->imageOffset, info->imageExtent),
.layers = MAX2(info->imageExtent.depth, info->imageSubresource.layerCount),
- }, true);
+ .type = TU_BLIT_COPY,
+ });
}
static void
.dst = tu_blit_surf_ext(dst_image, info->dstSubresource, info->dstOffset, info->extent),
.src = tu_blit_surf_ext(src_image, info->srcSubresource, info->srcOffset, info->extent),
.layers = info->extent.depth,
- }, true);
+ .type = TU_BLIT_COPY,
+ });
}
void
.dst = tu_blit_surf_ext(dst_image, info->dstSubresource, info->dstOffset, info->extent),
.src = tu_blit_surf_ext(src_image, info->srcSubresource, info->srcOffset, info->extent),
.layers = MAX2(info->extent.depth, info->dstSubresource.layerCount)
- }, false);
+ });
}
void
tu_pack_clear_value(const VkClearValue *val,
VkFormat format,
uint32_t buf[4]);
+
+void
+tu_2d_clear_color(const VkClearColorValue *val, VkFormat format, uint32_t buf[4]);
+
+void
+tu_2d_clear_zs(const VkClearDepthStencilValue *val, VkFormat format, uint32_t buf[4]);
+
enum a6xx_2d_ifmt tu6_rb_fmt_to_ifmt(enum a6xx_color_fmt fmt);
enum a6xx_depth_format tu6_pipe2depth(VkFormat format);
VK_FORMAT_R64G64B64A64_UINT , plain, 1, 1, up64, up64, up64, up64, xyzw, rgb
VK_FORMAT_R64G64B64A64_SINT , plain, 1, 1, sp64, sp64, sp64, sp64, xyzw, rgb
VK_FORMAT_R64G64B64A64_SFLOAT , plain, 1, 1, f64 , f64 , f64 , f64 , xyzw, rgb
-VK_FORMAT_B10G11R11_UFLOAT_PACK32 , other, 1, 1, x32 , , , , xyz1, rgb
+VK_FORMAT_B10G11R11_UFLOAT_PACK32 , plain, 1, 1, f10 , f11 , f11 , , xyz1, rgb
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 , other, 1, 1, x32 , , , , xyz1, rgb
VK_FORMAT_D16_UNORM , plain, 1, 1, un16, , , , x___, zs
VK_FORMAT_X8_D24_UNORM_PACK32 , plain, 1, 1, un24, x8 , , , x___, zs