r2d_setup_common(struct tu_cmd_buffer *cmd,
struct tu_cs *cs,
VkFormat vk_format,
+ VkImageAspectFlags aspect_mask,
enum a6xx_rotation rotation,
bool clear,
- uint8_t mask,
bool scissor)
{
enum a6xx_format format = tu6_base_format(vk_format);
enum a6xx_2d_ifmt ifmt = format_to_ifmt(format);
uint32_t unknown_8c01 = 0;
- if (format == FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8) {
- /* preserve depth channels */
- if (mask == 0x8)
- unknown_8c01 = 0x00084001;
+ /* note: the only format with partial clearing is D24S8 */
+ if (vk_format == VK_FORMAT_D24_UNORM_S8_UINT) {
/* preserve stencil channel */
- if (mask == 0x7)
+ if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT)
unknown_8c01 = 0x08000041;
+ /* preserve depth channels */
+ if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
+ unknown_8c01 = 0x00084001;
}
tu_cs_emit_pkt4(cs, REG_A6XX_RB_UNKNOWN_8C01, 1);
r2d_setup(struct tu_cmd_buffer *cmd,
struct tu_cs *cs,
VkFormat vk_format,
+ VkImageAspectFlags aspect_mask,
enum a6xx_rotation rotation,
- bool clear,
- uint8_t mask)
+ bool clear)
{
tu_emit_cache_flush_ccu(cmd, cs, TU_CMD_CCU_SYSMEM);
- r2d_setup_common(cmd, cs, vk_format, rotation, clear, mask, false);
+ r2d_setup_common(cmd, cs, vk_format, aspect_mask, rotation, clear, false);
}
static void
tu_cs_emit_regs(cs, A6XX_RB_RENDER_CNTL());
}
+static uint8_t
+aspect_write_mask(VkFormat vk_format, VkImageAspectFlags aspect_mask)
+{
+ uint8_t mask = 0xf;
+ assert(aspect_mask);
+ /* note: the only format with partial writing is D24S8,
+ * clear/blit uses the _AS_R8G8B8A8 format to access it
+ */
+ if (vk_format == VK_FORMAT_D24_UNORM_S8_UINT) {
+ if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT)
+ mask = 0x7;
+ if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
+ mask = 0x8;
+ }
+ return mask;
+}
+
static void
r3d_setup(struct tu_cmd_buffer *cmd,
struct tu_cs *cs,
VkFormat vk_format,
+ VkImageAspectFlags aspect_mask,
enum a6xx_rotation rotation,
- bool clear,
- uint8_t mask)
+ bool clear)
{
if (!cmd->state.pass) {
tu_emit_cache_flush_ccu(cmd, cs, TU_CMD_CCU_SYSMEM);
.color_sint = vk_format_is_sint(vk_format),
.color_uint = vk_format_is_uint(vk_format)));
- tu_cs_emit_regs(cs, A6XX_RB_MRT_CONTROL(0, .component_enable = mask));
+ tu_cs_emit_regs(cs, A6XX_RB_MRT_CONTROL(0,
+ .component_enable = aspect_write_mask(vk_format, aspect_mask)));
tu_cs_emit_regs(cs, A6XX_RB_SRGB_CNTL(vk_format_is_srgb(vk_format)));
tu_cs_emit_regs(cs, A6XX_SP_SRGB_CNTL(vk_format_is_srgb(vk_format)));
}
void (*setup)(struct tu_cmd_buffer *cmd,
struct tu_cs *cs,
VkFormat vk_format,
+ VkImageAspectFlags aspect_mask,
enum a6xx_rotation rotation,
- bool clear,
- uint8_t mask);
+ bool clear);
void (*run)(struct tu_cmd_buffer *cmd, struct tu_cs *cs);
};
layers = info->dstSubresource.layerCount;
}
- uint8_t mask = 0xf;
- if (dst_image->vk_format == VK_FORMAT_D24_UNORM_S8_UINT) {
- assert(info->srcSubresource.aspectMask == info->dstSubresource.aspectMask);
- if (info->dstSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
- mask = 0x7;
- if (info->dstSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
- mask = 0x8;
- }
-
/* BC1_RGB_* formats need to have their last components overriden with 1
* when sampling, which is normally handled with the texture descriptor
* swizzle. The 2d path can't handle that, so use the 3d path.
* figure out why (should be able to pass all tests with only shader path)
*/
- ops->setup(cmd, cs, dst_image->vk_format, rotate[mirror_y][mirror_x], false, mask);
+ ops->setup(cmd, cs, dst_image->vk_format, info->dstSubresource.aspectMask,
+ rotate[mirror_y][mirror_x], false);
if (ops == &r3d_ops) {
r3d_coords_raw(cs, false, (float[]) {
VkFormat src_format = dst_image->vk_format;
const struct blit_ops *ops = &r2d_ops;
- uint8_t mask = 0xf;
-
- if (dst_image->vk_format == VK_FORMAT_D24_UNORM_S8_UINT) {
- switch (info->imageSubresource.aspectMask) {
- case VK_IMAGE_ASPECT_STENCIL_BIT:
- src_format = VK_FORMAT_R8_UNORM; /* changes how src buffer is interpreted */
- mask = 0x8;
- ops = &r3d_ops;
- break;
- case VK_IMAGE_ASPECT_DEPTH_BIT:
- mask = 0x7;
- break;
- }
+ /* special case for buffer to stencil */
+ if (dst_format == VK_FORMAT_D24_UNORM_S8_UINT &&
+ info->imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
+ src_format = VK_FORMAT_R8_UNORM;
+ ops = &r3d_ops;
}
VkOffset3D offset = info->imageOffset;
uint32_t pitch = src_width * vk_format_get_blocksize(src_format);
uint32_t layer_size = src_height * pitch;
- ops->setup(cmd, cs, dst_format, ROTATE_0, false, mask);
+ ops->setup(cmd, cs, dst_format, info->imageSubresource.aspectMask, ROTATE_0, false);
struct tu_image_view dst;
tu_image_view_blit2(&dst, dst_image, dst_format, &info->imageSubresource, offset.z, false);
uint32_t pitch = dst_width * vk_format_get_blocksize(dst_format);
uint32_t layer_size = pitch * dst_height;
- ops->setup(cmd, cs, dst_format, ROTATE_0, false, 0xf);
+ ops->setup(cmd, cs, dst_format, VK_IMAGE_ASPECT_COLOR_BIT, ROTATE_0, false);
struct tu_image_view src;
tu_image_view_blit2(&src, src_image, src_format, &info->imageSubresource, offset.z, stencil_read);
const struct blit_ops *ops = &r2d_ops;
struct tu_cs *cs = &cmd->cs;
- uint8_t mask = 0xf;
- if (dst_image->vk_format == VK_FORMAT_D24_UNORM_S8_UINT) {
- if (info->dstSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
- mask = 0x7;
- if (info->dstSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
- mask = 0x8;
- }
-
if (dst_image->samples > 1)
ops = &r3d_ops;
tu_image_view_blit2(&staging, &staging_image, src_format,
&staging_subresource, 0, false);
- ops->setup(cmd, cs, src_format, ROTATE_0, false, mask);
+ ops->setup(cmd, cs, src_format, VK_IMAGE_ASPECT_COLOR_BIT, ROTATE_0, false);
coords(ops, cs, &staging_offset, &src_offset, &extent);
for (uint32_t i = 0; i < info->extent.depth; i++) {
tu_image_view_blit2(&staging, &staging_image, dst_format,
&staging_subresource, 0, false);
- ops->setup(cmd, cs, dst_format, ROTATE_0, false, mask);
+ ops->setup(cmd, cs, dst_format, info->dstSubresource.aspectMask, ROTATE_0, false);
coords(ops, cs, &dst_offset, &staging_offset, &extent);
for (uint32_t i = 0; i < info->extent.depth; i++) {
tu_image_view_blit2(&dst, dst_image, format, &info->dstSubresource, dst_offset.z, false);
tu_image_view_blit2(&src, src_image, format, &info->srcSubresource, src_offset.z, false);
- ops->setup(cmd, cs, format, ROTATE_0, false, mask);
+ ops->setup(cmd, cs, format, info->dstSubresource.aspectMask, ROTATE_0, false);
coords(ops, cs, &dst_offset, &src_offset, &extent);
for (uint32_t i = 0; i < info->extent.depth; i++) {
VkFormat format = block_size == 4 ? VK_FORMAT_R32_UINT : VK_FORMAT_R8_UNORM;
uint64_t blocks = size / block_size;
- ops->setup(cmd, cs, format, ROTATE_0, false, 0xf);
+ ops->setup(cmd, cs, format, VK_IMAGE_ASPECT_COLOR_BIT, ROTATE_0, false);
while (blocks) {
uint32_t src_x = (src_va & 63) / block_size;
uint64_t dst_va = tu_buffer_iova(buffer) + dstOffset;
uint32_t blocks = fillSize / 4;
- ops->setup(cmd, cs, VK_FORMAT_R32_UINT, ROTATE_0, true, 0xf);
+ ops->setup(cmd, cs, VK_FORMAT_R32_UINT, VK_IMAGE_ASPECT_COLOR_BIT, ROTATE_0, true);
ops->clear_value(cs, VK_FORMAT_R32_UINT, &(VkClearValue){.color = {.uint32[0] = data}});
while (blocks) {
tu_bo_list_add(&cmd->bo_list, src_image->bo, MSM_SUBMIT_BO_READ);
tu_bo_list_add(&cmd->bo_list, dst_image->bo, MSM_SUBMIT_BO_WRITE);
- ops->setup(cmd, cs, dst_image->vk_format, ROTATE_0, false, 0xf);
+ ops->setup(cmd, cs, dst_image->vk_format, VK_IMAGE_ASPECT_COLOR_BIT, ROTATE_0, false);
for (uint32_t i = 0; i < regionCount; ++i) {
const VkImageResolve *info = &pRegions[i];
assert(src->image->vk_format == dst->image->vk_format);
- ops->setup(cmd, cs, dst->image->vk_format, ROTATE_0, false, 0xf);
+ ops->setup(cmd, cs, dst->image->vk_format, VK_IMAGE_ASPECT_COLOR_BIT, ROTATE_0, false);
ops->coords(cs, &rect->offset, &rect->offset, &rect->extent);
for (uint32_t i = 0; i < layers; i++) {
assert(range->baseArrayLayer == 0);
}
- uint8_t mask = 0xf;
- if (image->vk_format == VK_FORMAT_D24_UNORM_S8_UINT) {
- mask = 0;
- if (range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
- mask |= 0x7;
- if (range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
- mask |= 0x8;
- }
-
const struct blit_ops *ops = image->samples > 1 ? &r3d_ops : &r2d_ops;
- ops->setup(cmd, cs, format, ROTATE_0, true, mask);
+ ops->setup(cmd, cs, format, range->aspectMask, ROTATE_0, true);
ops->clear_value(cs, image->vk_format, clear_value);
for (unsigned j = 0; j < level_count; j++) {
if (a == VK_ATTACHMENT_UNUSED)
continue;
- uint8_t mask = 0xf;
- if (cmd->state.pass->attachments[a].format == VK_FORMAT_D24_UNORM_S8_UINT) {
- if (!(attachments[j].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT))
- mask &= ~0x7;
- if (!(attachments[j].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT))
- mask &= ~0x8;
- }
-
const struct tu_image_view *iview =
cmd->state.framebuffer->attachments[a].attachment;
- ops->setup(cmd, cs, iview->image->vk_format, ROTATE_0, true, mask);
+ ops->setup(cmd, cs, iview->image->vk_format, attachments[j].aspectMask, ROTATE_0, true);
ops->clear_value(cs, iview->image->vk_format, &attachments[j].clearValue);
/* Wait for the flushes we triggered manually to complete */
tu_emit_clear_gmem_attachment(struct tu_cmd_buffer *cmd,
struct tu_cs *cs,
uint32_t attachment,
- uint8_t component_mask,
+ VkImageAspectFlags mask,
const VkClearValue *value)
{
VkFormat vk_format = cmd->state.pass->attachments[attachment].format;
- /* note: component_mask is 0x7 for depth and 0x8 for stencil
- * because D24S8 is cleared with AS_R8G8B8A8 format
- */
+
tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_DST_INFO, 1);
tu_cs_emit(cs, A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(tu6_base_format(vk_format)));
- tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_INFO, 1);
- tu_cs_emit(cs, A6XX_RB_BLIT_INFO_GMEM | A6XX_RB_BLIT_INFO_CLEAR_MASK(component_mask));
+ tu_cs_emit_regs(cs, A6XX_RB_BLIT_INFO(.gmem = 1,
+ .clear_mask = aspect_write_mask(vk_format, mask)));
tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_BASE_GMEM, 1);
tu_cs_emit(cs, cmd->state.pass->attachments[attachment].gmem_offset);
if (a == VK_ATTACHMENT_UNUSED)
continue;
- unsigned clear_mask = 0xf;
- if (cmd->state.pass->attachments[a].format == VK_FORMAT_D24_UNORM_S8_UINT) {
- if (!(attachments[j].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT))
- clear_mask &= ~0x7;
- if (!(attachments[j].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT))
- clear_mask &= ~0x8;
- }
-
- tu_emit_clear_gmem_attachment(cmd, cs, a, clear_mask,
+ tu_emit_clear_gmem_attachment(cmd, cs, a, attachments[j].aspectMask,
&attachments[j].clearValue);
}
}
const struct tu_image_view *iview = fb->attachments[a].attachment;
const struct tu_render_pass_attachment *attachment =
&cmd->state.pass->attachments[a];
- uint8_t mask = 0;
- if (attachment->clear_mask == VK_IMAGE_ASPECT_COLOR_BIT)
- mask = 0xf;
- if (attachment->clear_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
- mask |= 0x7;
- if (attachment->clear_mask & VK_IMAGE_ASPECT_STENCIL_BIT)
- mask |= 0x8;
-
- if (!mask)
+ if (!attachment->clear_mask)
return;
const struct blit_ops *ops = &r2d_ops;
if (attachment->samples > 1)
ops = &r3d_ops;
- ops->setup(cmd, cs, attachment->format, ROTATE_0, true, mask);
+ ops->setup(cmd, cs, attachment->format, attachment->clear_mask, ROTATE_0, true);
ops->coords(cs, &info->renderArea.offset, NULL, &info->renderArea.extent);
ops->clear_value(cs, attachment->format, &info->pClearValues[a]);
{
const struct tu_render_pass_attachment *attachment =
&cmd->state.pass->attachments[a];
- unsigned clear_mask = 0;
-
- if (attachment->clear_mask == VK_IMAGE_ASPECT_COLOR_BIT)
- clear_mask = 0xf;
- if (attachment->clear_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
- clear_mask |= 0x7;
- if (attachment->clear_mask & VK_IMAGE_ASPECT_STENCIL_BIT)
- clear_mask |= 0x8;
- if (!clear_mask)
+ if (!attachment->clear_mask)
return;
tu_cs_emit_regs(cs, A6XX_RB_MSAA_CNTL(tu_msaa_samples(attachment->samples)));
- tu_emit_clear_gmem_attachment(cmd, cs, a, clear_mask,
+ tu_emit_clear_gmem_attachment(cmd, cs, a, attachment->clear_mask,
&info->pClearValues[a]);
}
return;
}
- r2d_setup_common(cmd, cs, dst->format, ROTATE_0, false, 0xf, true);
+ r2d_setup_common(cmd, cs, dst->format, VK_IMAGE_ASPECT_COLOR_BIT, ROTATE_0, false, true);
r2d_dst(cs, iview, 0);
r2d_coords(cs, &render_area->offset, &render_area->offset, &render_area->extent);