turnip: implement CmdClearColorImage/CmdClearDepthStencilImage

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
This commit is contained in:
Jonathan Marek 2019-11-18 18:41:23 -05:00
parent 7eb7969213
commit d68acdb3b9
10 changed files with 194 additions and 34 deletions

View File

@ -96,6 +96,7 @@ emit_blit_step(struct tu_cmd_buffer *cmdbuf, const struct tu_blit *blt)
}
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) |
@ -110,23 +111,31 @@ emit_blit_step(struct tu_cmd_buffer *cmdbuf, const struct tu_blit *blt)
/*
* 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));
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);
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:
@ -182,9 +191,10 @@ emit_blit_step(struct tu_cmd_buffer *cmdbuf, const struct tu_blit *blt)
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;
@ -225,7 +235,14 @@ void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt, bool copy)
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);
}
@ -244,7 +261,7 @@ void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt, bool copy)
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;
@ -264,7 +281,7 @@ void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt, bool copy)
}
} 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;

View File

@ -79,13 +79,25 @@ tu_blit_surf_ext(struct tu_image *image,
}
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;
@ -93,8 +105,10 @@ struct tu_blit {
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 */

View File

@ -1153,10 +1153,10 @@ tu6_render_end(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
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);
});
}
}

View File

@ -631,6 +631,75 @@ 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])
{
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,

View File

@ -64,7 +64,7 @@ tu_blit_image(struct tu_cmd_buffer *cmdbuf,
.rotation = rotate[mirror_y][mirror_x],
};
tu_blit(cmdbuf, &blt, false);
tu_blit(cmdbuf, &blt);
}
void

View File

@ -22,6 +22,35 @@
*/
#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,
@ -31,6 +60,16 @@ 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
@ -41,6 +80,16 @@ tu_CmdClearDepthStencilImage(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_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
@ -50,4 +99,5 @@ tu_CmdClearAttachments(VkCommandBuffer commandBuffer,
uint32_t rectCount,
const VkClearRect *pRects)
{
tu_finishme("CmdClearAttachments");
}

View File

@ -233,7 +233,8 @@ tu_copy_buffer_to_image(struct tu_cmd_buffer *cmdbuf,
.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
@ -246,7 +247,8 @@ tu_copy_image_to_buffer(struct tu_cmd_buffer *cmdbuf,
.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
@ -267,7 +269,8 @@ tu_copy_image_to_image(struct tu_cmd_buffer *cmdbuf,
.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

View File

@ -43,7 +43,7 @@ tu_resolve_image(struct tu_cmd_buffer *cmdbuf,
.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

View File

@ -1229,6 +1229,13 @@ 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);

View File

@ -123,7 +123,7 @@ VK_FORMAT_R64G64B64_SFLOAT , plain, 1, 1, f64 , f64 , f64 , , xyz1
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

1 /* this is pretty much taken from the gallium one. */
123 VK_FORMAT_R64G64B64A64_SFLOAT , plain, 1, 1, f64 , f64 , f64 , f64 , xyzw, rgb
124 VK_FORMAT_B10G11R11_UFLOAT_PACK32 , other, 1, 1, x32 , , , , xyz1, rgb VK_FORMAT_B10G11R11_UFLOAT_PACK32 , plain, 1, 1, f10 , f11 , f11 , , xyz1, rgb
125 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 , other, 1, 1, x32 , , , , xyz1, rgb
126 VK_FORMAT_D16_UNORM , plain, 1, 1, un16, , , , x___, zs
127 VK_FORMAT_X8_D24_UNORM_PACK32 , plain, 1, 1, un24, x8 , , , x___, zs
128 VK_FORMAT_D32_SFLOAT , plain, 1, 1, f32 , , , , x___, zs
129 VK_FORMAT_S8_UINT , plain, 1, 1, up8 , , , , _x__, zs