mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 22:49:13 +02:00
panvk: Move common gfx bits to a new source file in the common dir
Keeping those distinct makes it hard to maintain (fixes hitting one version but not the other). Let's make it common code and guard CSF/JM specific code under #if PAN_ARCH blocks. Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31911>
This commit is contained in:
parent
79e5146378
commit
fd497b2278
5 changed files with 586 additions and 947 deletions
|
|
@ -434,116 +434,6 @@ translate_prim_topology(VkPrimitiveTopology in)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
force_fb_preload(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingInfo *render_info)
|
||||
{
|
||||
/* We force preloading for all active attachments when the render area is
|
||||
* unaligned or when a barrier flushes prior draw calls in the middle of a
|
||||
* render pass. The two cases can be distinguished by whether a
|
||||
* render_info is provided.
|
||||
*
|
||||
* When the render area is unaligned, we force preloading to preserve
|
||||
* contents falling outside of the render area. We also make sure the
|
||||
* initial attachment clears are performed.
|
||||
*/
|
||||
struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
|
||||
VkClearAttachment clear_atts[MAX_RTS + 2];
|
||||
uint32_t clear_att_count = 0;
|
||||
|
||||
if (!cmdbuf->state.gfx.render.bound_attachments)
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < fbinfo->rt_count; i++) {
|
||||
if (!fbinfo->rts[i].view)
|
||||
continue;
|
||||
|
||||
fbinfo->rts[i].preload = true;
|
||||
|
||||
if (fbinfo->rts[i].clear) {
|
||||
if (render_info) {
|
||||
const VkRenderingAttachmentInfo *att =
|
||||
&render_info->pColorAttachments[i];
|
||||
|
||||
clear_atts[clear_att_count++] = (VkClearAttachment){
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.colorAttachment = i,
|
||||
.clearValue = att->clearValue,
|
||||
};
|
||||
}
|
||||
fbinfo->rts[i].clear = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fbinfo->zs.view.zs) {
|
||||
fbinfo->zs.preload.z = true;
|
||||
|
||||
if (fbinfo->zs.clear.z) {
|
||||
if (render_info) {
|
||||
const VkRenderingAttachmentInfo *att =
|
||||
render_info->pDepthAttachment;
|
||||
|
||||
clear_atts[clear_att_count++] = (VkClearAttachment){
|
||||
.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
.clearValue = att->clearValue,
|
||||
};
|
||||
}
|
||||
fbinfo->zs.clear.z = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fbinfo->zs.view.s ||
|
||||
(fbinfo->zs.view.zs &&
|
||||
util_format_is_depth_and_stencil(fbinfo->zs.view.zs->format))) {
|
||||
fbinfo->zs.preload.s = true;
|
||||
|
||||
if (fbinfo->zs.clear.s) {
|
||||
if (render_info) {
|
||||
const VkRenderingAttachmentInfo *att =
|
||||
render_info->pStencilAttachment;
|
||||
|
||||
clear_atts[clear_att_count++] = (VkClearAttachment){
|
||||
.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||
.clearValue = att->clearValue,
|
||||
};
|
||||
}
|
||||
|
||||
fbinfo->zs.clear.s = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* insert a barrier for preload */
|
||||
const VkMemoryBarrier2 mem_barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT,
|
||||
};
|
||||
const VkDependencyInfo dep_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||
.memoryBarrierCount = 1,
|
||||
.pMemoryBarriers = &mem_barrier,
|
||||
};
|
||||
panvk_per_arch(CmdPipelineBarrier2)(panvk_cmd_buffer_to_handle(cmdbuf),
|
||||
&dep_info);
|
||||
|
||||
if (clear_att_count && render_info) {
|
||||
VkClearRect clear_rect = {
|
||||
.rect = render_info->renderArea,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = render_info->layerCount,
|
||||
};
|
||||
|
||||
panvk_per_arch(CmdClearAttachments)(panvk_cmd_buffer_to_handle(cmdbuf),
|
||||
clear_att_count, clear_atts, 1,
|
||||
&clear_rect);
|
||||
}
|
||||
}
|
||||
|
||||
static VkResult
|
||||
update_tls(struct panvk_cmd_buffer *cmdbuf)
|
||||
{
|
||||
|
|
@ -1704,242 +1594,6 @@ panvk_per_arch(CmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer,
|
|||
panvk_cmd_draw_indirect(cmdbuf, &draw);
|
||||
}
|
||||
|
||||
static void
|
||||
panvk_cmd_init_render_state(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingInfo *pRenderingInfo)
|
||||
{
|
||||
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
|
||||
struct panvk_physical_device *phys_dev =
|
||||
to_panvk_physical_device(dev->vk.physical);
|
||||
struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
|
||||
uint32_t att_width = 0, att_height = 0;
|
||||
|
||||
cmdbuf->state.gfx.render.flags = pRenderingInfo->flags;
|
||||
|
||||
gfx_state_set_dirty(cmdbuf, RENDER_STATE);
|
||||
memset(cmdbuf->state.gfx.render.fb.crc_valid, 0,
|
||||
sizeof(cmdbuf->state.gfx.render.fb.crc_valid));
|
||||
memset(&cmdbuf->state.gfx.render.color_attachments, 0,
|
||||
sizeof(cmdbuf->state.gfx.render.color_attachments));
|
||||
memset(&cmdbuf->state.gfx.render.z_attachment, 0,
|
||||
sizeof(cmdbuf->state.gfx.render.z_attachment));
|
||||
memset(&cmdbuf->state.gfx.render.s_attachment, 0,
|
||||
sizeof(cmdbuf->state.gfx.render.s_attachment));
|
||||
cmdbuf->state.gfx.render.bound_attachments = 0;
|
||||
|
||||
cmdbuf->state.gfx.render.layer_count = pRenderingInfo->layerCount;
|
||||
*fbinfo = (struct pan_fb_info){
|
||||
.tile_buf_budget = panfrost_query_optimal_tib_size(phys_dev->model),
|
||||
.nr_samples = 1,
|
||||
.rt_count = pRenderingInfo->colorAttachmentCount,
|
||||
};
|
||||
|
||||
assert(pRenderingInfo->colorAttachmentCount <= ARRAY_SIZE(fbinfo->rts));
|
||||
|
||||
for (uint32_t i = 0; i < pRenderingInfo->colorAttachmentCount; i++) {
|
||||
const VkRenderingAttachmentInfo *att =
|
||||
&pRenderingInfo->pColorAttachments[i];
|
||||
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
|
||||
|
||||
if (!iview)
|
||||
continue;
|
||||
|
||||
struct panvk_image *img =
|
||||
container_of(iview->vk.image, struct panvk_image, vk);
|
||||
const VkExtent3D iview_size = iview->vk.extent;
|
||||
|
||||
cmdbuf->state.gfx.render.bound_attachments |=
|
||||
MESA_VK_RP_ATTACHMENT_COLOR_BIT(i);
|
||||
cmdbuf->state.gfx.render.color_attachments.iviews[i] = iview;
|
||||
cmdbuf->state.gfx.render.color_attachments.fmts[i] = iview->vk.format;
|
||||
cmdbuf->state.gfx.render.color_attachments.samples[i] = img->vk.samples;
|
||||
att_width = MAX2(iview_size.width, att_width);
|
||||
att_height = MAX2(iview_size.height, att_height);
|
||||
|
||||
fbinfo->rts[i].view = &iview->pview;
|
||||
fbinfo->rts[i].crc_valid = &cmdbuf->state.gfx.render.fb.crc_valid[i];
|
||||
fbinfo->nr_samples =
|
||||
MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview));
|
||||
|
||||
if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
|
||||
enum pipe_format fmt = vk_format_to_pipe_format(iview->vk.format);
|
||||
union pipe_color_union *col =
|
||||
(union pipe_color_union *)&att->clearValue.color;
|
||||
|
||||
fbinfo->rts[i].clear = true;
|
||||
pan_pack_color(phys_dev->formats.blendable, fbinfo->rts[i].clear_value,
|
||||
col, fmt, false);
|
||||
} else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) {
|
||||
fbinfo->rts[i].preload = true;
|
||||
}
|
||||
|
||||
if (att->resolveMode != VK_RESOLVE_MODE_NONE) {
|
||||
struct panvk_resolve_attachment *resolve_info =
|
||||
&cmdbuf->state.gfx.render.color_attachments.resolve[i];
|
||||
VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView);
|
||||
|
||||
resolve_info->mode = att->resolveMode;
|
||||
resolve_info->dst_iview = resolve_iview;
|
||||
}
|
||||
}
|
||||
|
||||
if (pRenderingInfo->pDepthAttachment &&
|
||||
pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE) {
|
||||
const VkRenderingAttachmentInfo *att = pRenderingInfo->pDepthAttachment;
|
||||
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
|
||||
struct panvk_image *img =
|
||||
container_of(iview->vk.image, struct panvk_image, vk);
|
||||
const VkExtent3D iview_size = iview->vk.extent;
|
||||
cmdbuf->state.gfx.render.z_attachment.fmt = iview->vk.format;
|
||||
|
||||
if (iview->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
|
||||
cmdbuf->state.gfx.render.bound_attachments |=
|
||||
MESA_VK_RP_ATTACHMENT_DEPTH_BIT;
|
||||
att_width = MAX2(iview_size.width, att_width);
|
||||
att_height = MAX2(iview_size.height, att_height);
|
||||
|
||||
fbinfo->zs.view.zs = &iview->pview;
|
||||
fbinfo->nr_samples = MAX2(
|
||||
fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview));
|
||||
cmdbuf->state.gfx.render.z_attachment.iview = iview;
|
||||
|
||||
if (vk_format_has_stencil(img->vk.format))
|
||||
fbinfo->zs.preload.s = true;
|
||||
|
||||
if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
|
||||
fbinfo->zs.clear.z = true;
|
||||
fbinfo->zs.clear_value.depth = att->clearValue.depthStencil.depth;
|
||||
} else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) {
|
||||
fbinfo->zs.preload.z = true;
|
||||
}
|
||||
|
||||
if (att->resolveMode != VK_RESOLVE_MODE_NONE) {
|
||||
struct panvk_resolve_attachment *resolve_info =
|
||||
&cmdbuf->state.gfx.render.z_attachment.resolve;
|
||||
VK_FROM_HANDLE(panvk_image_view, resolve_iview,
|
||||
att->resolveImageView);
|
||||
|
||||
resolve_info->mode = att->resolveMode;
|
||||
resolve_info->dst_iview = resolve_iview;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pRenderingInfo->pStencilAttachment &&
|
||||
pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) {
|
||||
const VkRenderingAttachmentInfo *att = pRenderingInfo->pStencilAttachment;
|
||||
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
|
||||
struct panvk_image *img =
|
||||
container_of(iview->vk.image, struct panvk_image, vk);
|
||||
const VkExtent3D iview_size = iview->vk.extent;
|
||||
cmdbuf->state.gfx.render.s_attachment.fmt = iview->vk.format;
|
||||
|
||||
if (iview->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||
cmdbuf->state.gfx.render.bound_attachments |=
|
||||
MESA_VK_RP_ATTACHMENT_STENCIL_BIT;
|
||||
att_width = MAX2(iview_size.width, att_width);
|
||||
att_height = MAX2(iview_size.height, att_height);
|
||||
|
||||
if (drm_is_afbc(img->pimage.layout.modifier)) {
|
||||
assert(fbinfo->zs.view.zs == &iview->pview || !fbinfo->zs.view.zs);
|
||||
fbinfo->zs.view.zs = &iview->pview;
|
||||
} else {
|
||||
fbinfo->zs.view.s =
|
||||
&iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL;
|
||||
}
|
||||
|
||||
fbinfo->zs.view.s =
|
||||
&iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL;
|
||||
fbinfo->nr_samples = MAX2(
|
||||
fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview));
|
||||
cmdbuf->state.gfx.render.s_attachment.iview = iview;
|
||||
|
||||
if (vk_format_has_depth(img->vk.format)) {
|
||||
assert(fbinfo->zs.view.zs == NULL ||
|
||||
&iview->pview == fbinfo->zs.view.zs);
|
||||
fbinfo->zs.view.zs = &iview->pview;
|
||||
|
||||
fbinfo->zs.preload.s = false;
|
||||
fbinfo->zs.clear.s = false;
|
||||
if (!fbinfo->zs.clear.z)
|
||||
fbinfo->zs.preload.z = true;
|
||||
}
|
||||
|
||||
if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
|
||||
fbinfo->zs.clear.s = true;
|
||||
fbinfo->zs.clear_value.stencil =
|
||||
att->clearValue.depthStencil.stencil;
|
||||
} else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) {
|
||||
fbinfo->zs.preload.s = true;
|
||||
}
|
||||
|
||||
if (att->resolveMode != VK_RESOLVE_MODE_NONE) {
|
||||
struct panvk_resolve_attachment *resolve_info =
|
||||
&cmdbuf->state.gfx.render.s_attachment.resolve;
|
||||
VK_FROM_HANDLE(panvk_image_view, resolve_iview,
|
||||
att->resolveImageView);
|
||||
|
||||
resolve_info->mode = att->resolveMode;
|
||||
resolve_info->dst_iview = resolve_iview;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fbinfo->zs.view.zs) {
|
||||
const struct util_format_description *fdesc =
|
||||
util_format_description(fbinfo->zs.view.zs->format);
|
||||
bool needs_depth = fbinfo->zs.clear.z | fbinfo->zs.preload.z |
|
||||
util_format_has_depth(fdesc);
|
||||
bool needs_stencil = fbinfo->zs.clear.s | fbinfo->zs.preload.s |
|
||||
util_format_has_stencil(fdesc);
|
||||
enum pipe_format new_fmt =
|
||||
util_format_get_blocksize(fbinfo->zs.view.zs->format) == 4
|
||||
? PIPE_FORMAT_Z24_UNORM_S8_UINT
|
||||
: PIPE_FORMAT_Z32_FLOAT_S8X24_UINT;
|
||||
|
||||
if (needs_depth && needs_stencil &&
|
||||
fbinfo->zs.view.zs->format != new_fmt) {
|
||||
cmdbuf->state.gfx.render.zs_pview = *fbinfo->zs.view.zs;
|
||||
cmdbuf->state.gfx.render.zs_pview.format = new_fmt;
|
||||
fbinfo->zs.view.zs = &cmdbuf->state.gfx.render.zs_pview;
|
||||
}
|
||||
}
|
||||
|
||||
fbinfo->extent.minx = pRenderingInfo->renderArea.offset.x;
|
||||
fbinfo->extent.maxx = pRenderingInfo->renderArea.offset.x +
|
||||
pRenderingInfo->renderArea.extent.width - 1;
|
||||
fbinfo->extent.miny = pRenderingInfo->renderArea.offset.y;
|
||||
fbinfo->extent.maxy = pRenderingInfo->renderArea.offset.y +
|
||||
pRenderingInfo->renderArea.extent.height - 1;
|
||||
|
||||
if (cmdbuf->state.gfx.render.bound_attachments) {
|
||||
fbinfo->width = att_width;
|
||||
fbinfo->height = att_height;
|
||||
} else {
|
||||
fbinfo->width = fbinfo->extent.maxx + 1;
|
||||
fbinfo->height = fbinfo->extent.maxy + 1;
|
||||
}
|
||||
|
||||
assert(fbinfo->width && fbinfo->height);
|
||||
}
|
||||
|
||||
static void
|
||||
preload_render_area_border(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingInfo *render_info)
|
||||
{
|
||||
struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
|
||||
bool render_area_is_32x32_aligned =
|
||||
((fbinfo->extent.minx | fbinfo->extent.miny) % 32) == 0 &&
|
||||
(fbinfo->extent.maxx + 1 == fbinfo->width ||
|
||||
(fbinfo->extent.maxx % 32) == 31) &&
|
||||
(fbinfo->extent.maxy + 1 == fbinfo->height ||
|
||||
(fbinfo->extent.maxy % 32) == 31);
|
||||
|
||||
/* If the render area is aligned on a 32x32 section, we're good. */
|
||||
if (!render_area_is_32x32_aligned)
|
||||
force_fb_preload(cmdbuf, render_info);
|
||||
}
|
||||
|
||||
void
|
||||
panvk_per_arch(cmd_inherit_render_state)(
|
||||
struct panvk_cmd_buffer *cmdbuf,
|
||||
|
|
@ -1956,7 +1610,7 @@ panvk_per_arch(cmd_inherit_render_state)(
|
|||
pBeginInfo,
|
||||
gcbiar_data);
|
||||
if (resume_info) {
|
||||
panvk_cmd_init_render_state(cmdbuf, resume_info);
|
||||
panvk_per_arch(cmd_init_render_state)(cmdbuf, resume_info);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2033,128 +1687,19 @@ panvk_per_arch(CmdBeginRendering)(VkCommandBuffer commandBuffer,
|
|||
{
|
||||
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
|
||||
struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
|
||||
|
||||
bool resuming = pRenderingInfo->flags & VK_RENDERING_RESUMING_BIT;
|
||||
|
||||
/* When resuming from a suspended pass, the state should be unchanged. */
|
||||
if (resuming)
|
||||
state->render.flags = pRenderingInfo->flags;
|
||||
else
|
||||
panvk_cmd_init_render_state(cmdbuf, pRenderingInfo);
|
||||
panvk_per_arch(cmd_init_render_state)(cmdbuf, pRenderingInfo);
|
||||
|
||||
/* If we're not resuming, the FBD should be NULL. */
|
||||
assert(!state->render.fbds.gpu || resuming);
|
||||
|
||||
if (!resuming)
|
||||
preload_render_area_border(cmdbuf, pRenderingInfo);
|
||||
}
|
||||
|
||||
static void
|
||||
resolve_attachments(struct panvk_cmd_buffer *cmdbuf)
|
||||
{
|
||||
struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
|
||||
bool needs_resolve = false;
|
||||
|
||||
unsigned bound_atts = cmdbuf->state.gfx.render.bound_attachments;
|
||||
unsigned color_att_count =
|
||||
util_last_bit(bound_atts & MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS);
|
||||
VkRenderingAttachmentInfo color_atts[MAX_RTS];
|
||||
for (uint32_t i = 0; i < color_att_count; i++) {
|
||||
const struct panvk_resolve_attachment *resolve_info =
|
||||
&cmdbuf->state.gfx.render.color_attachments.resolve[i];
|
||||
struct panvk_image_view *src_iview =
|
||||
cmdbuf->state.gfx.render.color_attachments.iviews[i];
|
||||
|
||||
color_atts[i] = (VkRenderingAttachmentInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = panvk_image_view_to_handle(src_iview),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.resolveMode = resolve_info->mode,
|
||||
.resolveImageView =
|
||||
panvk_image_view_to_handle(resolve_info->dst_iview),
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
if (resolve_info->mode != VK_RESOLVE_MODE_NONE)
|
||||
needs_resolve = true;
|
||||
}
|
||||
|
||||
const struct panvk_resolve_attachment *resolve_info =
|
||||
&cmdbuf->state.gfx.render.z_attachment.resolve;
|
||||
struct panvk_image_view *src_iview =
|
||||
cmdbuf->state.gfx.render.z_attachment.iview;
|
||||
VkRenderingAttachmentInfo z_att = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = panvk_image_view_to_handle(src_iview),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.resolveMode = resolve_info->mode,
|
||||
.resolveImageView = panvk_image_view_to_handle(resolve_info->dst_iview),
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
if (resolve_info->mode != VK_RESOLVE_MODE_NONE)
|
||||
needs_resolve = true;
|
||||
|
||||
resolve_info = &cmdbuf->state.gfx.render.s_attachment.resolve;
|
||||
src_iview = cmdbuf->state.gfx.render.s_attachment.iview;
|
||||
|
||||
VkRenderingAttachmentInfo s_att = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = panvk_image_view_to_handle(src_iview),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.resolveMode = resolve_info->mode,
|
||||
.resolveImageView = panvk_image_view_to_handle(resolve_info->dst_iview),
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
if (resolve_info->mode != VK_RESOLVE_MODE_NONE)
|
||||
needs_resolve = true;
|
||||
|
||||
if (!needs_resolve)
|
||||
return;
|
||||
|
||||
/* insert a barrier for resolve */
|
||||
const VkMemoryBarrier2 mem_barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT,
|
||||
};
|
||||
const VkDependencyInfo dep_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||
.memoryBarrierCount = 1,
|
||||
.pMemoryBarriers = &mem_barrier,
|
||||
};
|
||||
panvk_per_arch(CmdPipelineBarrier2)(panvk_cmd_buffer_to_handle(cmdbuf),
|
||||
&dep_info);
|
||||
|
||||
const VkRenderingInfo render_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||
.renderArea =
|
||||
{
|
||||
.offset.x = fbinfo->extent.minx,
|
||||
.offset.y = fbinfo->extent.miny,
|
||||
.extent.width = fbinfo->extent.maxx - fbinfo->extent.minx + 1,
|
||||
.extent.height = fbinfo->extent.maxy - fbinfo->extent.miny + 1,
|
||||
},
|
||||
.layerCount = cmdbuf->state.gfx.render.layer_count,
|
||||
.viewMask = 0,
|
||||
.colorAttachmentCount = color_att_count,
|
||||
.pColorAttachments = color_atts,
|
||||
.pDepthAttachment = &z_att,
|
||||
.pStencilAttachment = &s_att,
|
||||
};
|
||||
|
||||
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
|
||||
struct panvk_cmd_meta_graphics_save_ctx save = {0};
|
||||
|
||||
panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
|
||||
vk_meta_resolve_rendering(&cmdbuf->vk, &dev->meta, &render_info);
|
||||
panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
|
||||
panvk_per_arch(cmd_preload_render_area_border)(cmdbuf, pRenderingInfo);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
|
|
@ -2473,7 +2018,7 @@ panvk_per_arch(cmd_flush_draws)(struct panvk_cmd_buffer *cmdbuf)
|
|||
sizeof(cmdbuf->state.gfx.render.fbds));
|
||||
cmdbuf->state.gfx.render.tiler = 0;
|
||||
|
||||
force_fb_preload(cmdbuf, NULL);
|
||||
panvk_per_arch(cmd_force_fb_preload)(cmdbuf, NULL);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
|
|
@ -2495,45 +2040,6 @@ panvk_per_arch(CmdEndRendering)(VkCommandBuffer commandBuffer)
|
|||
|
||||
flush_tiling(cmdbuf);
|
||||
issue_fragment_jobs(cmdbuf);
|
||||
resolve_attachments(cmdbuf);
|
||||
panvk_per_arch(cmd_resolve_attachments)(cmdbuf);
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
panvk_per_arch(CmdBindVertexBuffers)(VkCommandBuffer commandBuffer,
|
||||
uint32_t firstBinding,
|
||||
uint32_t bindingCount,
|
||||
const VkBuffer *pBuffers,
|
||||
const VkDeviceSize *pOffsets)
|
||||
{
|
||||
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
|
||||
|
||||
assert(firstBinding + bindingCount <= MAX_VBS);
|
||||
|
||||
for (uint32_t i = 0; i < bindingCount; i++) {
|
||||
VK_FROM_HANDLE(panvk_buffer, buffer, pBuffers[i]);
|
||||
|
||||
cmdbuf->state.gfx.vb.bufs[firstBinding + i].address =
|
||||
panvk_buffer_gpu_ptr(buffer, pOffsets[i]);
|
||||
cmdbuf->state.gfx.vb.bufs[firstBinding + i].size =
|
||||
panvk_buffer_range(buffer, pOffsets[i], VK_WHOLE_SIZE);
|
||||
}
|
||||
|
||||
cmdbuf->state.gfx.vb.count =
|
||||
MAX2(cmdbuf->state.gfx.vb.count, firstBinding + bindingCount);
|
||||
gfx_state_set_dirty(cmdbuf, VB);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
panvk_per_arch(CmdBindIndexBuffer)(VkCommandBuffer commandBuffer,
|
||||
VkBuffer buffer, VkDeviceSize offset,
|
||||
VkIndexType indexType)
|
||||
{
|
||||
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
|
||||
VK_FROM_HANDLE(panvk_buffer, buf, buffer);
|
||||
|
||||
cmdbuf->state.gfx.ib.buffer = buf;
|
||||
cmdbuf->state.gfx.ib.offset = offset;
|
||||
cmdbuf->state.gfx.ib.index_size = vk_index_type_to_bytes(indexType);
|
||||
gfx_state_set_dirty(cmdbuf, IB);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1493,332 +1493,20 @@ panvk_per_arch(CmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer,
|
|||
panvk_stub();
|
||||
}
|
||||
|
||||
static void
|
||||
panvk_cmd_begin_rendering_init_state(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingInfo *pRenderingInfo)
|
||||
{
|
||||
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
|
||||
struct panvk_physical_device *phys_dev =
|
||||
to_panvk_physical_device(dev->vk.physical);
|
||||
struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
|
||||
uint32_t att_width = 0, att_height = 0;
|
||||
|
||||
cmdbuf->state.gfx.render.flags = pRenderingInfo->flags;
|
||||
|
||||
/* Resuming from a suspended pass, the state should be unchanged. */
|
||||
if (cmdbuf->state.gfx.render.flags & VK_RENDERING_RESUMING_BIT)
|
||||
return;
|
||||
|
||||
gfx_state_set_dirty(cmdbuf, RENDER_STATE);
|
||||
cmdbuf->state.gfx.render.fb.bo_count = 0;
|
||||
memset(cmdbuf->state.gfx.render.fb.bos, 0,
|
||||
sizeof(cmdbuf->state.gfx.render.fb.bos));
|
||||
memset(cmdbuf->state.gfx.render.fb.crc_valid, 0,
|
||||
sizeof(cmdbuf->state.gfx.render.fb.crc_valid));
|
||||
memset(&cmdbuf->state.gfx.render.color_attachments, 0,
|
||||
sizeof(cmdbuf->state.gfx.render.color_attachments));
|
||||
memset(&cmdbuf->state.gfx.render.z_attachment, 0,
|
||||
sizeof(cmdbuf->state.gfx.render.z_attachment));
|
||||
memset(&cmdbuf->state.gfx.render.s_attachment, 0,
|
||||
sizeof(cmdbuf->state.gfx.render.s_attachment));
|
||||
cmdbuf->state.gfx.render.bound_attachments = 0;
|
||||
|
||||
cmdbuf->state.gfx.render.layer_count = pRenderingInfo->layerCount;
|
||||
*fbinfo = (struct pan_fb_info){
|
||||
.tile_buf_budget = panfrost_query_optimal_tib_size(phys_dev->model),
|
||||
.nr_samples = 1,
|
||||
.rt_count = pRenderingInfo->colorAttachmentCount,
|
||||
};
|
||||
|
||||
assert(pRenderingInfo->colorAttachmentCount <= ARRAY_SIZE(fbinfo->rts));
|
||||
|
||||
for (uint32_t i = 0; i < pRenderingInfo->colorAttachmentCount; i++) {
|
||||
const VkRenderingAttachmentInfo *att =
|
||||
&pRenderingInfo->pColorAttachments[i];
|
||||
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
|
||||
|
||||
if (!iview)
|
||||
continue;
|
||||
|
||||
struct panvk_image *img =
|
||||
container_of(iview->vk.image, struct panvk_image, vk);
|
||||
const VkExtent3D iview_size = iview->vk.extent;
|
||||
|
||||
cmdbuf->state.gfx.render.bound_attachments |=
|
||||
MESA_VK_RP_ATTACHMENT_COLOR_BIT(i);
|
||||
cmdbuf->state.gfx.render.color_attachments.iviews[i] = iview;
|
||||
cmdbuf->state.gfx.render.color_attachments.fmts[i] = iview->vk.format;
|
||||
cmdbuf->state.gfx.render.color_attachments.samples[i] = img->vk.samples;
|
||||
att_width = MAX2(iview_size.width, att_width);
|
||||
att_height = MAX2(iview_size.height, att_height);
|
||||
|
||||
cmdbuf->state.gfx.render.fb.bos[cmdbuf->state.gfx.render.fb.bo_count++] =
|
||||
img->bo;
|
||||
fbinfo->rts[i].view = &iview->pview;
|
||||
fbinfo->rts[i].crc_valid = &cmdbuf->state.gfx.render.fb.crc_valid[i];
|
||||
fbinfo->nr_samples =
|
||||
MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview));
|
||||
|
||||
if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
|
||||
enum pipe_format fmt = vk_format_to_pipe_format(iview->vk.format);
|
||||
union pipe_color_union *col =
|
||||
(union pipe_color_union *)&att->clearValue.color;
|
||||
|
||||
fbinfo->rts[i].clear = true;
|
||||
pan_pack_color(phys_dev->formats.blendable, fbinfo->rts[i].clear_value,
|
||||
col, fmt, false);
|
||||
} else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) {
|
||||
fbinfo->rts[i].preload = true;
|
||||
}
|
||||
|
||||
if (att->resolveMode != VK_RESOLVE_MODE_NONE) {
|
||||
struct panvk_resolve_attachment *resolve_info =
|
||||
&cmdbuf->state.gfx.render.color_attachments.resolve[i];
|
||||
VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView);
|
||||
|
||||
resolve_info->mode = att->resolveMode;
|
||||
resolve_info->dst_iview = resolve_iview;
|
||||
}
|
||||
}
|
||||
|
||||
if (pRenderingInfo->pDepthAttachment &&
|
||||
pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE) {
|
||||
const VkRenderingAttachmentInfo *att = pRenderingInfo->pDepthAttachment;
|
||||
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
|
||||
struct panvk_image *img =
|
||||
container_of(iview->vk.image, struct panvk_image, vk);
|
||||
const VkExtent3D iview_size = iview->vk.extent;
|
||||
cmdbuf->state.gfx.render.z_attachment.fmt = iview->vk.format;
|
||||
|
||||
if (iview->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
|
||||
cmdbuf->state.gfx.render.bound_attachments |=
|
||||
MESA_VK_RP_ATTACHMENT_DEPTH_BIT;
|
||||
att_width = MAX2(iview_size.width, att_width);
|
||||
att_height = MAX2(iview_size.height, att_height);
|
||||
|
||||
cmdbuf->state.gfx.render.fb
|
||||
.bos[cmdbuf->state.gfx.render.fb.bo_count++] = img->bo;
|
||||
fbinfo->zs.view.zs = &iview->pview;
|
||||
fbinfo->nr_samples = MAX2(
|
||||
fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview));
|
||||
cmdbuf->state.gfx.render.z_attachment.iview = iview;
|
||||
|
||||
if (vk_format_has_stencil(img->vk.format))
|
||||
fbinfo->zs.preload.s = true;
|
||||
|
||||
if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
|
||||
fbinfo->zs.clear.z = true;
|
||||
fbinfo->zs.clear_value.depth = att->clearValue.depthStencil.depth;
|
||||
} else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) {
|
||||
fbinfo->zs.preload.z = true;
|
||||
}
|
||||
|
||||
if (att->resolveMode != VK_RESOLVE_MODE_NONE) {
|
||||
struct panvk_resolve_attachment *resolve_info =
|
||||
&cmdbuf->state.gfx.render.z_attachment.resolve;
|
||||
VK_FROM_HANDLE(panvk_image_view, resolve_iview,
|
||||
att->resolveImageView);
|
||||
|
||||
resolve_info->mode = att->resolveMode;
|
||||
resolve_info->dst_iview = resolve_iview;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pRenderingInfo->pStencilAttachment &&
|
||||
pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) {
|
||||
const VkRenderingAttachmentInfo *att = pRenderingInfo->pStencilAttachment;
|
||||
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
|
||||
struct panvk_image *img =
|
||||
container_of(iview->vk.image, struct panvk_image, vk);
|
||||
const VkExtent3D iview_size = iview->vk.extent;
|
||||
cmdbuf->state.gfx.render.s_attachment.fmt = iview->vk.format;
|
||||
|
||||
if (iview->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||
cmdbuf->state.gfx.render.bound_attachments |=
|
||||
MESA_VK_RP_ATTACHMENT_STENCIL_BIT;
|
||||
att_width = MAX2(iview_size.width, att_width);
|
||||
att_height = MAX2(iview_size.height, att_height);
|
||||
|
||||
cmdbuf->state.gfx.render.fb
|
||||
.bos[cmdbuf->state.gfx.render.fb.bo_count++] = img->bo;
|
||||
|
||||
if (drm_is_afbc(img->pimage.layout.modifier)) {
|
||||
assert(fbinfo->zs.view.zs == &iview->pview || !fbinfo->zs.view.zs);
|
||||
fbinfo->zs.view.zs = &iview->pview;
|
||||
} else {
|
||||
fbinfo->zs.view.s =
|
||||
&iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL;
|
||||
}
|
||||
|
||||
fbinfo->zs.view.s =
|
||||
&iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL;
|
||||
fbinfo->nr_samples = MAX2(
|
||||
fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview));
|
||||
cmdbuf->state.gfx.render.s_attachment.iview = iview;
|
||||
|
||||
if (vk_format_has_depth(img->vk.format)) {
|
||||
assert(fbinfo->zs.view.zs == NULL ||
|
||||
&iview->pview == fbinfo->zs.view.zs);
|
||||
fbinfo->zs.view.zs = &iview->pview;
|
||||
|
||||
fbinfo->zs.preload.s = false;
|
||||
fbinfo->zs.clear.s = false;
|
||||
if (!fbinfo->zs.clear.z)
|
||||
fbinfo->zs.preload.z = true;
|
||||
}
|
||||
|
||||
if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
|
||||
fbinfo->zs.clear.s = true;
|
||||
fbinfo->zs.clear_value.stencil =
|
||||
att->clearValue.depthStencil.stencil;
|
||||
} else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) {
|
||||
fbinfo->zs.preload.s = true;
|
||||
}
|
||||
|
||||
if (att->resolveMode != VK_RESOLVE_MODE_NONE) {
|
||||
struct panvk_resolve_attachment *resolve_info =
|
||||
&cmdbuf->state.gfx.render.s_attachment.resolve;
|
||||
VK_FROM_HANDLE(panvk_image_view, resolve_iview,
|
||||
att->resolveImageView);
|
||||
|
||||
resolve_info->mode = att->resolveMode;
|
||||
resolve_info->dst_iview = resolve_iview;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fbinfo->zs.view.zs) {
|
||||
const struct util_format_description *fdesc =
|
||||
util_format_description(fbinfo->zs.view.zs->format);
|
||||
bool needs_depth = fbinfo->zs.clear.z | fbinfo->zs.preload.z |
|
||||
util_format_has_depth(fdesc);
|
||||
bool needs_stencil = fbinfo->zs.clear.s | fbinfo->zs.preload.s |
|
||||
util_format_has_stencil(fdesc);
|
||||
enum pipe_format new_fmt =
|
||||
util_format_get_blocksize(fbinfo->zs.view.zs->format) == 4
|
||||
? PIPE_FORMAT_Z24_UNORM_S8_UINT
|
||||
: PIPE_FORMAT_Z32_FLOAT_S8X24_UINT;
|
||||
|
||||
if (needs_depth && needs_stencil &&
|
||||
fbinfo->zs.view.zs->format != new_fmt) {
|
||||
cmdbuf->state.gfx.render.zs_pview = *fbinfo->zs.view.zs;
|
||||
cmdbuf->state.gfx.render.zs_pview.format = new_fmt;
|
||||
fbinfo->zs.view.zs = &cmdbuf->state.gfx.render.zs_pview;
|
||||
}
|
||||
}
|
||||
|
||||
fbinfo->extent.minx = pRenderingInfo->renderArea.offset.x;
|
||||
fbinfo->extent.maxx = pRenderingInfo->renderArea.offset.x +
|
||||
pRenderingInfo->renderArea.extent.width - 1;
|
||||
fbinfo->extent.miny = pRenderingInfo->renderArea.offset.y;
|
||||
fbinfo->extent.maxy = pRenderingInfo->renderArea.offset.y +
|
||||
pRenderingInfo->renderArea.extent.height - 1;
|
||||
|
||||
if (cmdbuf->state.gfx.render.bound_attachments) {
|
||||
fbinfo->width = att_width;
|
||||
fbinfo->height = att_height;
|
||||
} else {
|
||||
fbinfo->width = fbinfo->extent.maxx + 1;
|
||||
fbinfo->height = fbinfo->extent.maxy + 1;
|
||||
}
|
||||
|
||||
assert(fbinfo->width && fbinfo->height);
|
||||
}
|
||||
|
||||
static void
|
||||
preload_render_area_border(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingInfo *render_info)
|
||||
{
|
||||
struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
|
||||
bool render_area_is_32x32_aligned =
|
||||
((fbinfo->extent.minx | fbinfo->extent.miny) % 32) == 0 &&
|
||||
(fbinfo->extent.maxx + 1 == fbinfo->width ||
|
||||
(fbinfo->extent.maxx % 32) == 31) &&
|
||||
(fbinfo->extent.maxy + 1 == fbinfo->height ||
|
||||
(fbinfo->extent.maxy % 32) == 31);
|
||||
|
||||
/* If the render area is aligned on a 32x32 section, we're good. */
|
||||
if (render_area_is_32x32_aligned)
|
||||
return;
|
||||
|
||||
/* We force preloading for all active attachments to preverse content falling
|
||||
* outside the render area, but we need to compensate with attachment clears
|
||||
* for attachments that were initially cleared.
|
||||
*/
|
||||
uint32_t bound_atts = cmdbuf->state.gfx.render.bound_attachments;
|
||||
VkClearAttachment clear_atts[MAX_RTS + 2];
|
||||
uint32_t clear_att_count = 0;
|
||||
|
||||
for (uint32_t i = 0; i < render_info->colorAttachmentCount; i++) {
|
||||
if (bound_atts & MESA_VK_RP_ATTACHMENT_COLOR_BIT(i)) {
|
||||
if (fbinfo->rts[i].clear) {
|
||||
const VkRenderingAttachmentInfo *att =
|
||||
&render_info->pColorAttachments[i];
|
||||
|
||||
clear_atts[clear_att_count++] = (VkClearAttachment){
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.colorAttachment = i,
|
||||
.clearValue = att->clearValue,
|
||||
};
|
||||
}
|
||||
|
||||
fbinfo->rts[i].preload = true;
|
||||
fbinfo->rts[i].clear = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (bound_atts & MESA_VK_RP_ATTACHMENT_DEPTH_BIT) {
|
||||
if (fbinfo->zs.clear.z) {
|
||||
const VkRenderingAttachmentInfo *att = render_info->pDepthAttachment;
|
||||
|
||||
clear_atts[clear_att_count++] = (VkClearAttachment){
|
||||
.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
.clearValue = att->clearValue,
|
||||
};
|
||||
}
|
||||
|
||||
fbinfo->zs.preload.z = true;
|
||||
fbinfo->zs.clear.z = false;
|
||||
}
|
||||
|
||||
if (bound_atts & MESA_VK_RP_ATTACHMENT_STENCIL_BIT) {
|
||||
if (fbinfo->zs.clear.s) {
|
||||
const VkRenderingAttachmentInfo *att = render_info->pStencilAttachment;
|
||||
|
||||
clear_atts[clear_att_count++] = (VkClearAttachment){
|
||||
.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||
.clearValue = att->clearValue,
|
||||
};
|
||||
}
|
||||
|
||||
fbinfo->zs.preload.s = true;
|
||||
fbinfo->zs.clear.s = false;
|
||||
}
|
||||
|
||||
if (clear_att_count) {
|
||||
VkClearRect clear_rect = {
|
||||
.rect = render_info->renderArea,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = render_info->layerCount,
|
||||
};
|
||||
|
||||
panvk_per_arch(CmdClearAttachments)(panvk_cmd_buffer_to_handle(cmdbuf),
|
||||
clear_att_count, clear_atts, 1,
|
||||
&clear_rect);
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
panvk_per_arch(CmdBeginRendering)(VkCommandBuffer commandBuffer,
|
||||
const VkRenderingInfo *pRenderingInfo)
|
||||
{
|
||||
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
|
||||
|
||||
panvk_cmd_begin_rendering_init_state(cmdbuf, pRenderingInfo);
|
||||
|
||||
struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
|
||||
bool resuming = cmdbuf->state.gfx.render.flags & VK_RENDERING_RESUMING_BIT;
|
||||
|
||||
/* When resuming from a suspended pass, the state should be unchanged. */
|
||||
if (resuming)
|
||||
state->render.flags = pRenderingInfo->flags;
|
||||
else
|
||||
panvk_per_arch(cmd_init_render_state)(cmdbuf, pRenderingInfo);
|
||||
|
||||
/* If we're not resuming, cur_batch should be NULL.
|
||||
* However, this currently isn't true because of how events are implemented.
|
||||
* XXX: Rewrite events to not close and open batch and add an assert here.
|
||||
|
|
@ -1835,95 +1523,7 @@ panvk_per_arch(CmdBeginRendering)(VkCommandBuffer commandBuffer,
|
|||
panvk_per_arch(cmd_open_batch)(cmdbuf);
|
||||
|
||||
if (!resuming)
|
||||
preload_render_area_border(cmdbuf, pRenderingInfo);
|
||||
}
|
||||
|
||||
static void
|
||||
resolve_attachments(struct panvk_cmd_buffer *cmdbuf)
|
||||
{
|
||||
struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
|
||||
bool needs_resolve = false;
|
||||
|
||||
unsigned bound_atts = cmdbuf->state.gfx.render.bound_attachments;
|
||||
unsigned color_att_count =
|
||||
util_last_bit(bound_atts & MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS);
|
||||
VkRenderingAttachmentInfo color_atts[MAX_RTS];
|
||||
for (uint32_t i = 0; i < color_att_count; i++) {
|
||||
const struct panvk_resolve_attachment *resolve_info =
|
||||
&cmdbuf->state.gfx.render.color_attachments.resolve[i];
|
||||
struct panvk_image_view *src_iview =
|
||||
cmdbuf->state.gfx.render.color_attachments.iviews[i];
|
||||
|
||||
color_atts[i] = (VkRenderingAttachmentInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = panvk_image_view_to_handle(src_iview),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.resolveMode = resolve_info->mode,
|
||||
.resolveImageView =
|
||||
panvk_image_view_to_handle(resolve_info->dst_iview),
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
if (resolve_info->mode != VK_RESOLVE_MODE_NONE)
|
||||
needs_resolve = true;
|
||||
}
|
||||
|
||||
const struct panvk_resolve_attachment *resolve_info =
|
||||
&cmdbuf->state.gfx.render.z_attachment.resolve;
|
||||
struct panvk_image_view *src_iview =
|
||||
cmdbuf->state.gfx.render.z_attachment.iview;
|
||||
VkRenderingAttachmentInfo z_att = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = panvk_image_view_to_handle(src_iview),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.resolveMode = resolve_info->mode,
|
||||
.resolveImageView = panvk_image_view_to_handle(resolve_info->dst_iview),
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
if (resolve_info->mode != VK_RESOLVE_MODE_NONE)
|
||||
needs_resolve = true;
|
||||
|
||||
resolve_info = &cmdbuf->state.gfx.render.s_attachment.resolve;
|
||||
src_iview = cmdbuf->state.gfx.render.s_attachment.iview;
|
||||
|
||||
VkRenderingAttachmentInfo s_att = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = panvk_image_view_to_handle(src_iview),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.resolveMode = resolve_info->mode,
|
||||
.resolveImageView = panvk_image_view_to_handle(resolve_info->dst_iview),
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
if (resolve_info->mode != VK_RESOLVE_MODE_NONE)
|
||||
needs_resolve = true;
|
||||
|
||||
if (!needs_resolve)
|
||||
return;
|
||||
|
||||
const VkRenderingInfo render_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||
.renderArea = {
|
||||
.offset.x = fbinfo->extent.minx,
|
||||
.offset.y = fbinfo->extent.miny,
|
||||
.extent.width = fbinfo->extent.maxx - fbinfo->extent.minx + 1,
|
||||
.extent.height = fbinfo->extent.maxy - fbinfo->extent.miny + 1,
|
||||
},
|
||||
.layerCount = cmdbuf->state.gfx.render.layer_count,
|
||||
.viewMask = 0,
|
||||
.colorAttachmentCount = color_att_count,
|
||||
.pColorAttachments = color_atts,
|
||||
.pDepthAttachment = &z_att,
|
||||
.pStencilAttachment = &s_att,
|
||||
};
|
||||
|
||||
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
|
||||
struct panvk_cmd_meta_graphics_save_ctx save = {0};
|
||||
|
||||
panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
|
||||
vk_meta_resolve_rendering(&cmdbuf->vk, &dev->meta, &render_info);
|
||||
panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
|
||||
panvk_per_arch(cmd_preload_render_area_border)(cmdbuf, pRenderingInfo);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
|
|
@ -1942,45 +1542,6 @@ panvk_per_arch(CmdEndRendering)(VkCommandBuffer commandBuffer)
|
|||
|
||||
panvk_per_arch(cmd_close_batch)(cmdbuf);
|
||||
cmdbuf->cur_batch = NULL;
|
||||
resolve_attachments(cmdbuf);
|
||||
panvk_per_arch(cmd_resolve_attachments)(cmdbuf);
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
panvk_per_arch(CmdBindVertexBuffers)(VkCommandBuffer commandBuffer,
|
||||
uint32_t firstBinding,
|
||||
uint32_t bindingCount,
|
||||
const VkBuffer *pBuffers,
|
||||
const VkDeviceSize *pOffsets)
|
||||
{
|
||||
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
|
||||
|
||||
assert(firstBinding + bindingCount <= MAX_VBS);
|
||||
|
||||
for (uint32_t i = 0; i < bindingCount; i++) {
|
||||
VK_FROM_HANDLE(panvk_buffer, buffer, pBuffers[i]);
|
||||
|
||||
cmdbuf->state.gfx.vb.bufs[firstBinding + i].address =
|
||||
panvk_buffer_gpu_ptr(buffer, pOffsets[i]);
|
||||
cmdbuf->state.gfx.vb.bufs[firstBinding + i].size =
|
||||
panvk_buffer_range(buffer, pOffsets[i], VK_WHOLE_SIZE);
|
||||
}
|
||||
|
||||
cmdbuf->state.gfx.vb.count =
|
||||
MAX2(cmdbuf->state.gfx.vb.count, firstBinding + bindingCount);
|
||||
gfx_state_set_dirty(cmdbuf, VB);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
panvk_per_arch(CmdBindIndexBuffer)(VkCommandBuffer commandBuffer,
|
||||
VkBuffer buffer, VkDeviceSize offset,
|
||||
VkIndexType indexType)
|
||||
{
|
||||
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
|
||||
VK_FROM_HANDLE(panvk_buffer, buf, buffer);
|
||||
|
||||
cmdbuf->state.gfx.ib.buffer = buf;
|
||||
cmdbuf->state.gfx.ib.offset = offset;
|
||||
cmdbuf->state.gfx.ib.index_size = vk_index_type_to_bytes(indexType);
|
||||
gfx_state_set_dirty(cmdbuf, IB);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ common_per_arch_files = [
|
|||
'panvk_vX_buffer_view.c',
|
||||
'panvk_vX_cmd_fb_preload.c',
|
||||
'panvk_vX_cmd_desc_state.c',
|
||||
'panvk_vX_cmd_draw.c',
|
||||
'panvk_vX_cmd_meta.c',
|
||||
'panvk_vX_cmd_push_constant.c',
|
||||
'panvk_vX_descriptor_set.c',
|
||||
|
|
|
|||
|
|
@ -11,13 +11,21 @@
|
|||
#endif
|
||||
|
||||
#include "panvk_blend.h"
|
||||
#include "panvk_entrypoints.h"
|
||||
#include "panvk_image.h"
|
||||
#include "panvk_image_view.h"
|
||||
#include "panvk_physical_device.h"
|
||||
|
||||
#include "vk_command_buffer.h"
|
||||
#include "vk_format.h"
|
||||
|
||||
#include "pan_props.h"
|
||||
|
||||
#define MAX_VBS 16
|
||||
#define MAX_RTS 8
|
||||
|
||||
struct panvk_cmd_buffer;
|
||||
|
||||
struct panvk_attrib_buf {
|
||||
mali_ptr address;
|
||||
unsigned size;
|
||||
|
|
@ -247,4 +255,18 @@ fs_required(const struct panvk_cmd_graphics_state *state,
|
|||
gfx_state_set_dirty(__cmdbuf, FS); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
panvk_per_arch(cmd_init_render_state)(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingInfo *pRenderingInfo);
|
||||
|
||||
void
|
||||
panvk_per_arch(cmd_force_fb_preload)(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingInfo *render_info);
|
||||
|
||||
void
|
||||
panvk_per_arch(cmd_preload_render_area_border)(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingInfo *render_info);
|
||||
|
||||
void panvk_per_arch(cmd_resolve_attachments)(struct panvk_cmd_buffer *cmdbuf);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
549
src/panfrost/vulkan/panvk_vX_cmd_draw.c
Normal file
549
src/panfrost/vulkan/panvk_vX_cmd_draw.c
Normal file
|
|
@ -0,0 +1,549 @@
|
|||
/*
|
||||
* Copyright © 2024 Collabora Ltd.
|
||||
* Copyright © 2024 Arm Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "panvk_buffer.h"
|
||||
#include "panvk_cmd_buffer.h"
|
||||
#include "panvk_cmd_meta.h"
|
||||
#include "panvk_entrypoints.h"
|
||||
|
||||
static void
|
||||
render_state_set_color_attachment(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingAttachmentInfo *att,
|
||||
uint32_t index)
|
||||
{
|
||||
struct panvk_physical_device *phys_dev =
|
||||
to_panvk_physical_device(cmdbuf->vk.base.device->physical);
|
||||
struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
|
||||
struct pan_fb_info *fbinfo = &state->render.fb.info;
|
||||
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
|
||||
struct panvk_image *img =
|
||||
container_of(iview->vk.image, struct panvk_image, vk);
|
||||
|
||||
state->render.bound_attachments |= MESA_VK_RP_ATTACHMENT_COLOR_BIT(index);
|
||||
state->render.color_attachments.iviews[index] = iview;
|
||||
state->render.color_attachments.fmts[index] = iview->vk.format;
|
||||
state->render.color_attachments.samples[index] = img->vk.samples;
|
||||
|
||||
#if PAN_ARCH <= 7
|
||||
state->render.fb.bos[state->render.fb.bo_count++] = img->bo;
|
||||
#endif
|
||||
|
||||
fbinfo->rts[index].view = &iview->pview;
|
||||
fbinfo->rts[index].crc_valid = &state->render.fb.crc_valid[index];
|
||||
fbinfo->nr_samples =
|
||||
MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview));
|
||||
|
||||
if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
|
||||
enum pipe_format fmt = vk_format_to_pipe_format(iview->vk.format);
|
||||
union pipe_color_union *col =
|
||||
(union pipe_color_union *)&att->clearValue.color;
|
||||
|
||||
fbinfo->rts[index].clear = true;
|
||||
pan_pack_color(phys_dev->formats.blendable,
|
||||
fbinfo->rts[index].clear_value, col, fmt, false);
|
||||
} else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) {
|
||||
fbinfo->rts[index].preload = true;
|
||||
}
|
||||
|
||||
if (att->resolveMode != VK_RESOLVE_MODE_NONE) {
|
||||
struct panvk_resolve_attachment *resolve_info =
|
||||
&state->render.color_attachments.resolve[index];
|
||||
VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView);
|
||||
|
||||
resolve_info->mode = att->resolveMode;
|
||||
resolve_info->dst_iview = resolve_iview;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
render_state_set_z_attachment(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingAttachmentInfo *att)
|
||||
{
|
||||
struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
|
||||
struct pan_fb_info *fbinfo = &state->render.fb.info;
|
||||
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
|
||||
struct panvk_image *img =
|
||||
container_of(iview->vk.image, struct panvk_image, vk);
|
||||
|
||||
#if PAN_ARCH <= 7
|
||||
state->render.fb.bos[state->render.fb.bo_count++] = img->bo;
|
||||
#endif
|
||||
|
||||
state->render.z_attachment.fmt = iview->vk.format;
|
||||
state->render.bound_attachments |= MESA_VK_RP_ATTACHMENT_DEPTH_BIT;
|
||||
fbinfo->zs.view.zs = &iview->pview;
|
||||
fbinfo->nr_samples =
|
||||
MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview));
|
||||
state->render.z_attachment.iview = iview;
|
||||
|
||||
if (vk_format_has_stencil(img->vk.format))
|
||||
fbinfo->zs.preload.s = true;
|
||||
|
||||
if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
|
||||
fbinfo->zs.clear.z = true;
|
||||
fbinfo->zs.clear_value.depth = att->clearValue.depthStencil.depth;
|
||||
} else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) {
|
||||
fbinfo->zs.preload.z = true;
|
||||
}
|
||||
|
||||
if (att->resolveMode != VK_RESOLVE_MODE_NONE) {
|
||||
struct panvk_resolve_attachment *resolve_info =
|
||||
&state->render.z_attachment.resolve;
|
||||
VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView);
|
||||
|
||||
resolve_info->mode = att->resolveMode;
|
||||
resolve_info->dst_iview = resolve_iview;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
render_state_set_s_attachment(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingAttachmentInfo *att)
|
||||
{
|
||||
struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
|
||||
struct pan_fb_info *fbinfo = &state->render.fb.info;
|
||||
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
|
||||
struct panvk_image *img =
|
||||
container_of(iview->vk.image, struct panvk_image, vk);
|
||||
|
||||
#if PAN_ARCH <= 7
|
||||
state->render.fb.bos[state->render.fb.bo_count++] = img->bo;
|
||||
#endif
|
||||
|
||||
state->render.s_attachment.fmt = iview->vk.format;
|
||||
state->render.bound_attachments |= MESA_VK_RP_ATTACHMENT_STENCIL_BIT;
|
||||
|
||||
if (drm_is_afbc(img->pimage.layout.modifier)) {
|
||||
assert(fbinfo->zs.view.zs == &iview->pview || !fbinfo->zs.view.zs);
|
||||
fbinfo->zs.view.zs = &iview->pview;
|
||||
} else {
|
||||
fbinfo->zs.view.s =
|
||||
&iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL;
|
||||
}
|
||||
|
||||
fbinfo->zs.view.s =
|
||||
&iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL;
|
||||
fbinfo->nr_samples =
|
||||
MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview));
|
||||
state->render.s_attachment.iview = iview;
|
||||
|
||||
if (vk_format_has_depth(img->vk.format)) {
|
||||
assert(fbinfo->zs.view.zs == NULL || &iview->pview == fbinfo->zs.view.zs);
|
||||
fbinfo->zs.view.zs = &iview->pview;
|
||||
|
||||
fbinfo->zs.preload.s = false;
|
||||
fbinfo->zs.clear.s = false;
|
||||
if (!fbinfo->zs.clear.z)
|
||||
fbinfo->zs.preload.z = true;
|
||||
}
|
||||
|
||||
if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
|
||||
fbinfo->zs.clear.s = true;
|
||||
fbinfo->zs.clear_value.stencil = att->clearValue.depthStencil.stencil;
|
||||
} else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) {
|
||||
fbinfo->zs.preload.s = true;
|
||||
}
|
||||
|
||||
if (att->resolveMode != VK_RESOLVE_MODE_NONE) {
|
||||
struct panvk_resolve_attachment *resolve_info =
|
||||
&state->render.s_attachment.resolve;
|
||||
VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView);
|
||||
|
||||
resolve_info->mode = att->resolveMode;
|
||||
resolve_info->dst_iview = resolve_iview;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
panvk_per_arch(cmd_init_render_state)(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingInfo *pRenderingInfo)
|
||||
{
|
||||
struct panvk_physical_device *phys_dev =
|
||||
to_panvk_physical_device(cmdbuf->vk.base.device->physical);
|
||||
struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
|
||||
struct pan_fb_info *fbinfo = &state->render.fb.info;
|
||||
uint32_t att_width = 0, att_height = 0;
|
||||
|
||||
state->render.flags = pRenderingInfo->flags;
|
||||
|
||||
BITSET_SET(state->dirty, PANVK_CMD_GRAPHICS_DIRTY_RENDER_STATE);
|
||||
|
||||
#if PAN_ARCH <= 7
|
||||
state->render.fb.bo_count = 0;
|
||||
memset(state->render.fb.bos, 0, sizeof(state->render.fb.bos));
|
||||
#endif
|
||||
|
||||
memset(state->render.fb.crc_valid, 0, sizeof(state->render.fb.crc_valid));
|
||||
memset(&state->render.color_attachments, 0,
|
||||
sizeof(state->render.color_attachments));
|
||||
memset(&state->render.z_attachment, 0, sizeof(state->render.z_attachment));
|
||||
memset(&state->render.s_attachment, 0, sizeof(state->render.s_attachment));
|
||||
state->render.bound_attachments = 0;
|
||||
|
||||
state->render.layer_count = pRenderingInfo->layerCount;
|
||||
*fbinfo = (struct pan_fb_info){
|
||||
.tile_buf_budget = panfrost_query_optimal_tib_size(phys_dev->model),
|
||||
.nr_samples = 1,
|
||||
.rt_count = pRenderingInfo->colorAttachmentCount,
|
||||
};
|
||||
|
||||
assert(pRenderingInfo->colorAttachmentCount <= ARRAY_SIZE(fbinfo->rts));
|
||||
|
||||
for (uint32_t i = 0; i < pRenderingInfo->colorAttachmentCount; i++) {
|
||||
const VkRenderingAttachmentInfo *att =
|
||||
&pRenderingInfo->pColorAttachments[i];
|
||||
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
|
||||
|
||||
if (!iview)
|
||||
continue;
|
||||
|
||||
render_state_set_color_attachment(cmdbuf, att, i);
|
||||
att_width = MAX2(iview->vk.extent.width, att_width);
|
||||
att_height = MAX2(iview->vk.extent.height, att_height);
|
||||
}
|
||||
|
||||
if (pRenderingInfo->pDepthAttachment &&
|
||||
pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE) {
|
||||
const VkRenderingAttachmentInfo *att = pRenderingInfo->pDepthAttachment;
|
||||
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
|
||||
|
||||
if (iview && (iview->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) {
|
||||
render_state_set_z_attachment(cmdbuf, att);
|
||||
att_width = MAX2(iview->vk.extent.width, att_width);
|
||||
att_height = MAX2(iview->vk.extent.height, att_height);
|
||||
}
|
||||
}
|
||||
|
||||
if (pRenderingInfo->pStencilAttachment &&
|
||||
pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) {
|
||||
const VkRenderingAttachmentInfo *att = pRenderingInfo->pStencilAttachment;
|
||||
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
|
||||
|
||||
if (iview && (iview->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||
render_state_set_s_attachment(cmdbuf, att);
|
||||
att_width = MAX2(iview->vk.extent.width, att_width);
|
||||
att_height = MAX2(iview->vk.extent.height, att_height);
|
||||
}
|
||||
}
|
||||
|
||||
if (fbinfo->zs.view.zs) {
|
||||
const struct util_format_description *fdesc =
|
||||
util_format_description(fbinfo->zs.view.zs->format);
|
||||
bool needs_depth = fbinfo->zs.clear.z | fbinfo->zs.preload.z |
|
||||
util_format_has_depth(fdesc);
|
||||
bool needs_stencil = fbinfo->zs.clear.s | fbinfo->zs.preload.s |
|
||||
util_format_has_stencil(fdesc);
|
||||
enum pipe_format new_fmt =
|
||||
util_format_get_blocksize(fbinfo->zs.view.zs->format) == 4
|
||||
? PIPE_FORMAT_Z24_UNORM_S8_UINT
|
||||
: PIPE_FORMAT_Z32_FLOAT_S8X24_UINT;
|
||||
|
||||
if (needs_depth && needs_stencil &&
|
||||
fbinfo->zs.view.zs->format != new_fmt) {
|
||||
state->render.zs_pview = *fbinfo->zs.view.zs;
|
||||
state->render.zs_pview.format = new_fmt;
|
||||
fbinfo->zs.view.zs = &state->render.zs_pview;
|
||||
}
|
||||
}
|
||||
|
||||
fbinfo->extent.minx = pRenderingInfo->renderArea.offset.x;
|
||||
fbinfo->extent.maxx = pRenderingInfo->renderArea.offset.x +
|
||||
pRenderingInfo->renderArea.extent.width - 1;
|
||||
fbinfo->extent.miny = pRenderingInfo->renderArea.offset.y;
|
||||
fbinfo->extent.maxy = pRenderingInfo->renderArea.offset.y +
|
||||
pRenderingInfo->renderArea.extent.height - 1;
|
||||
|
||||
if (state->render.bound_attachments) {
|
||||
fbinfo->width = att_width;
|
||||
fbinfo->height = att_height;
|
||||
} else {
|
||||
fbinfo->width = fbinfo->extent.maxx + 1;
|
||||
fbinfo->height = fbinfo->extent.maxy + 1;
|
||||
}
|
||||
|
||||
assert(fbinfo->width && fbinfo->height);
|
||||
}
|
||||
|
||||
void
|
||||
panvk_per_arch(cmd_resolve_attachments)(struct panvk_cmd_buffer *cmdbuf)
|
||||
{
|
||||
struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info;
|
||||
bool needs_resolve = false;
|
||||
|
||||
unsigned bound_atts = cmdbuf->state.gfx.render.bound_attachments;
|
||||
unsigned color_att_count =
|
||||
util_last_bit(bound_atts & MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS);
|
||||
VkRenderingAttachmentInfo color_atts[MAX_RTS];
|
||||
for (uint32_t i = 0; i < color_att_count; i++) {
|
||||
const struct panvk_resolve_attachment *resolve_info =
|
||||
&cmdbuf->state.gfx.render.color_attachments.resolve[i];
|
||||
struct panvk_image_view *src_iview =
|
||||
cmdbuf->state.gfx.render.color_attachments.iviews[i];
|
||||
|
||||
color_atts[i] = (VkRenderingAttachmentInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = panvk_image_view_to_handle(src_iview),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.resolveMode = resolve_info->mode,
|
||||
.resolveImageView =
|
||||
panvk_image_view_to_handle(resolve_info->dst_iview),
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
if (resolve_info->mode != VK_RESOLVE_MODE_NONE)
|
||||
needs_resolve = true;
|
||||
}
|
||||
|
||||
const struct panvk_resolve_attachment *resolve_info =
|
||||
&cmdbuf->state.gfx.render.z_attachment.resolve;
|
||||
struct panvk_image_view *src_iview =
|
||||
cmdbuf->state.gfx.render.z_attachment.iview;
|
||||
VkRenderingAttachmentInfo z_att = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = panvk_image_view_to_handle(src_iview),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.resolveMode = resolve_info->mode,
|
||||
.resolveImageView = panvk_image_view_to_handle(resolve_info->dst_iview),
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
if (resolve_info->mode != VK_RESOLVE_MODE_NONE)
|
||||
needs_resolve = true;
|
||||
|
||||
resolve_info = &cmdbuf->state.gfx.render.s_attachment.resolve;
|
||||
src_iview = cmdbuf->state.gfx.render.s_attachment.iview;
|
||||
|
||||
VkRenderingAttachmentInfo s_att = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = panvk_image_view_to_handle(src_iview),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.resolveMode = resolve_info->mode,
|
||||
.resolveImageView = panvk_image_view_to_handle(resolve_info->dst_iview),
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
if (resolve_info->mode != VK_RESOLVE_MODE_NONE)
|
||||
needs_resolve = true;
|
||||
|
||||
if (!needs_resolve)
|
||||
return;
|
||||
|
||||
#if PAN_ARCH >= 10
|
||||
/* insert a barrier for resolve */
|
||||
const VkMemoryBarrier2 mem_barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT
|
||||
};
|
||||
const VkDependencyInfo dep_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||
.memoryBarrierCount = 1,
|
||||
.pMemoryBarriers = &mem_barrier,
|
||||
};
|
||||
panvk_per_arch(CmdPipelineBarrier2)(panvk_cmd_buffer_to_handle(cmdbuf),
|
||||
&dep_info);
|
||||
#endif
|
||||
|
||||
const VkRenderingInfo render_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||
.renderArea =
|
||||
{
|
||||
.offset.x = fbinfo->extent.minx,
|
||||
.offset.y = fbinfo->extent.miny,
|
||||
.extent.width = fbinfo->extent.maxx - fbinfo->extent.minx + 1,
|
||||
.extent.height = fbinfo->extent.maxy - fbinfo->extent.miny + 1,
|
||||
},
|
||||
.layerCount = cmdbuf->state.gfx.render.layer_count,
|
||||
.viewMask = 0,
|
||||
.colorAttachmentCount = color_att_count,
|
||||
.pColorAttachments = color_atts,
|
||||
.pDepthAttachment = &z_att,
|
||||
.pStencilAttachment = &s_att,
|
||||
};
|
||||
|
||||
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
|
||||
struct panvk_cmd_meta_graphics_save_ctx save = {0};
|
||||
|
||||
panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
|
||||
vk_meta_resolve_rendering(&cmdbuf->vk, &dev->meta, &render_info);
|
||||
panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
|
||||
}
|
||||
|
||||
void
|
||||
panvk_per_arch(cmd_force_fb_preload)(struct panvk_cmd_buffer *cmdbuf,
|
||||
const VkRenderingInfo *render_info)
|
||||
{
|
||||
/* We force preloading for all active attachments when the render area is
|
||||
* unaligned or when a barrier flushes prior draw calls in the middle of a
|
||||
* render pass. The two cases can be distinguished by whether a
|
||||
* render_info is provided.
|
||||
*
|
||||
* When the render area is unaligned, we force preloading to preserve
|
||||
* contents falling outside of the render area. We also make sure the
|
||||
* initial attachment clears are performed.
|
||||
*/
|
||||
struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
|
||||
struct pan_fb_info *fbinfo = &state->render.fb.info;
|
||||
VkClearAttachment clear_atts[MAX_RTS + 2];
|
||||
uint32_t clear_att_count = 0;
|
||||
|
||||
if (!state->render.bound_attachments)
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < fbinfo->rt_count; i++) {
|
||||
if (!fbinfo->rts[i].view)
|
||||
continue;
|
||||
|
||||
fbinfo->rts[i].preload = true;
|
||||
|
||||
if (fbinfo->rts[i].clear) {
|
||||
if (render_info) {
|
||||
const VkRenderingAttachmentInfo *att =
|
||||
&render_info->pColorAttachments[i];
|
||||
|
||||
clear_atts[clear_att_count++] = (VkClearAttachment){
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.colorAttachment = i,
|
||||
.clearValue = att->clearValue,
|
||||
};
|
||||
}
|
||||
fbinfo->rts[i].clear = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fbinfo->zs.view.zs) {
|
||||
fbinfo->zs.preload.z = true;
|
||||
|
||||
if (fbinfo->zs.clear.z) {
|
||||
if (render_info) {
|
||||
const VkRenderingAttachmentInfo *att =
|
||||
render_info->pDepthAttachment;
|
||||
|
||||
clear_atts[clear_att_count++] = (VkClearAttachment){
|
||||
.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
.clearValue = att->clearValue,
|
||||
};
|
||||
}
|
||||
fbinfo->zs.clear.z = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fbinfo->zs.view.s ||
|
||||
(fbinfo->zs.view.zs &&
|
||||
util_format_is_depth_and_stencil(fbinfo->zs.view.zs->format))) {
|
||||
fbinfo->zs.preload.s = true;
|
||||
|
||||
if (fbinfo->zs.clear.s) {
|
||||
if (render_info) {
|
||||
const VkRenderingAttachmentInfo *att =
|
||||
render_info->pStencilAttachment;
|
||||
|
||||
clear_atts[clear_att_count++] = (VkClearAttachment){
|
||||
.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||
.clearValue = att->clearValue,
|
||||
};
|
||||
}
|
||||
|
||||
fbinfo->zs.clear.s = false;
|
||||
}
|
||||
}
|
||||
|
||||
#if PAN_ARCH >= 10
|
||||
/* insert a barrier for preload */
|
||||
const VkMemoryBarrier2 mem_barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT,
|
||||
};
|
||||
const VkDependencyInfo dep_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||
.memoryBarrierCount = 1,
|
||||
.pMemoryBarriers = &mem_barrier,
|
||||
};
|
||||
panvk_per_arch(CmdPipelineBarrier2)(panvk_cmd_buffer_to_handle(cmdbuf),
|
||||
&dep_info);
|
||||
#endif
|
||||
|
||||
if (clear_att_count && render_info) {
|
||||
VkClearRect clear_rect = {
|
||||
.rect = render_info->renderArea,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = render_info->layerCount,
|
||||
};
|
||||
|
||||
panvk_per_arch(CmdClearAttachments)(panvk_cmd_buffer_to_handle(cmdbuf),
|
||||
clear_att_count, clear_atts, 1,
|
||||
&clear_rect);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
panvk_per_arch(cmd_preload_render_area_border)(
|
||||
struct panvk_cmd_buffer *cmdbuf, const VkRenderingInfo *render_info)
|
||||
{
|
||||
struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
|
||||
struct pan_fb_info *fbinfo = &state->render.fb.info;
|
||||
bool render_area_is_32x32_aligned =
|
||||
((fbinfo->extent.minx | fbinfo->extent.miny) % 32) == 0 &&
|
||||
(fbinfo->extent.maxx + 1 == fbinfo->width ||
|
||||
(fbinfo->extent.maxx % 32) == 31) &&
|
||||
(fbinfo->extent.maxy + 1 == fbinfo->height ||
|
||||
(fbinfo->extent.maxy % 32) == 31);
|
||||
|
||||
/* If the render area is aligned on a 32x32 section, we're good. */
|
||||
if (!render_area_is_32x32_aligned)
|
||||
panvk_per_arch(cmd_force_fb_preload)(cmdbuf, render_info);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
panvk_per_arch(CmdBindVertexBuffers)(VkCommandBuffer commandBuffer,
|
||||
uint32_t firstBinding,
|
||||
uint32_t bindingCount,
|
||||
const VkBuffer *pBuffers,
|
||||
const VkDeviceSize *pOffsets)
|
||||
{
|
||||
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
|
||||
|
||||
assert(firstBinding + bindingCount <= MAX_VBS);
|
||||
|
||||
for (uint32_t i = 0; i < bindingCount; i++) {
|
||||
VK_FROM_HANDLE(panvk_buffer, buffer, pBuffers[i]);
|
||||
|
||||
cmdbuf->state.gfx.vb.bufs[firstBinding + i].address =
|
||||
panvk_buffer_gpu_ptr(buffer, pOffsets[i]);
|
||||
cmdbuf->state.gfx.vb.bufs[firstBinding + i].size =
|
||||
panvk_buffer_range(buffer, pOffsets[i], VK_WHOLE_SIZE);
|
||||
}
|
||||
|
||||
cmdbuf->state.gfx.vb.count =
|
||||
MAX2(cmdbuf->state.gfx.vb.count, firstBinding + bindingCount);
|
||||
gfx_state_set_dirty(cmdbuf, VB);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
panvk_per_arch(CmdBindIndexBuffer)(VkCommandBuffer commandBuffer,
|
||||
VkBuffer buffer, VkDeviceSize offset,
|
||||
VkIndexType indexType)
|
||||
{
|
||||
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
|
||||
VK_FROM_HANDLE(panvk_buffer, buf, buffer);
|
||||
|
||||
cmdbuf->state.gfx.ib.buffer = buf;
|
||||
cmdbuf->state.gfx.ib.offset = offset;
|
||||
cmdbuf->state.gfx.ib.index_size = vk_index_type_to_bytes(indexType);
|
||||
gfx_state_set_dirty(cmdbuf, IB);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue