panvk: Implement dynamic rendering entry points

Implement dynamic rendering entry points so we can get rid of the
render pass logic.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28167>
This commit is contained in:
Boris Brezillon 2023-12-15 14:39:18 +01:00 committed by Marge Bot
parent 8cba497701
commit 595d362d4b
8 changed files with 178 additions and 522 deletions

View file

@ -42,7 +42,6 @@ libpanvk_files = files(
'panvk_formats.c',
'panvk_image.c',
'panvk_mempool.c',
'panvk_pass.c',
'panvk_pipeline.c',
'panvk_private.h',
'panvk_query.c',

View file

@ -388,140 +388,6 @@ panvk_CreateCommandPool(VkDevice _device,
return VK_SUCCESS;
}
static void
panvk_cmd_prepare_clear_values(struct panvk_cmd_buffer *cmdbuf,
const VkClearValue *in)
{
for (unsigned i = 0; i < cmdbuf->state.pass->attachment_count; i++) {
const struct panvk_render_pass_attachment *attachment =
&cmdbuf->state.pass->attachments[i];
enum pipe_format fmt = attachment->format;
if (util_format_is_depth_or_stencil(fmt)) {
if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR ||
attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
cmdbuf->state.clear[i].depth = in[i].depthStencil.depth;
cmdbuf->state.clear[i].stencil = in[i].depthStencil.stencil;
} else {
cmdbuf->state.clear[i].depth = 0;
cmdbuf->state.clear[i].stencil = 0;
}
} else {
if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
union pipe_color_union *col =
(union pipe_color_union *)&in[i].color;
pan_pack_color(panfrost_blendable_formats_v7,
cmdbuf->state.clear[i].color, col, fmt, false);
} else {
memset(cmdbuf->state.clear[i].color, 0,
sizeof(cmdbuf->state.clear[0].color));
}
}
}
}
void
panvk_cmd_fb_info_set_subpass(struct panvk_cmd_buffer *cmdbuf)
{
const struct panvk_subpass *subpass = cmdbuf->state.subpass;
struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
const struct vk_framebuffer *fb = cmdbuf->state.framebuffer;
const struct panvk_clear_value *clears = cmdbuf->state.clear;
fbinfo->nr_samples = 1;
fbinfo->rt_count = subpass->color_count;
memset(&fbinfo->bifrost.pre_post.dcds, 0,
sizeof(fbinfo->bifrost.pre_post.dcds));
for (unsigned cb = 0; cb < subpass->color_count; cb++) {
int idx = subpass->color_attachments[cb].idx;
if (idx == VK_ATTACHMENT_UNUSED)
continue;
VK_FROM_HANDLE(panvk_image_view, view, fb->attachments[idx]);
fbinfo->rts[cb].view = &view->pview;
fbinfo->rts[cb].clear = subpass->color_attachments[cb].clear;
fbinfo->rts[cb].preload = subpass->color_attachments[cb].preload;
fbinfo->rts[cb].crc_valid = &cmdbuf->state.fb.crc_valid[cb];
memcpy(fbinfo->rts[cb].clear_value, clears[idx].color,
sizeof(fbinfo->rts[cb].clear_value));
fbinfo->nr_samples =
MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&view->pview));
}
if (subpass->zs_attachment.idx != VK_ATTACHMENT_UNUSED) {
VK_FROM_HANDLE(panvk_image_view, view,
fb->attachments[subpass->zs_attachment.idx]);
const struct util_format_description *fdesc =
util_format_description(view->pview.format);
fbinfo->nr_samples =
MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&view->pview));
if (util_format_has_depth(fdesc)) {
fbinfo->zs.clear.z = subpass->zs_attachment.clear;
fbinfo->zs.clear_value.depth =
clears[subpass->zs_attachment.idx].depth;
fbinfo->zs.view.zs = &view->pview;
}
if (util_format_has_stencil(fdesc)) {
fbinfo->zs.clear.s = subpass->zs_attachment.clear;
fbinfo->zs.clear_value.stencil =
clears[subpass->zs_attachment.idx].stencil;
if (!fbinfo->zs.view.zs)
fbinfo->zs.view.s = &view->pview;
}
}
}
void
panvk_cmd_fb_info_init(struct panvk_cmd_buffer *cmdbuf)
{
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.fb.info;
const struct vk_framebuffer *fb = cmdbuf->state.framebuffer;
memset(cmdbuf->state.fb.crc_valid, 0, sizeof(cmdbuf->state.fb.crc_valid));
*fbinfo = (struct pan_fb_info){
.tile_buf_budget = panfrost_query_optimal_tib_size(phys_dev->model),
.width = fb->width,
.height = fb->height,
.extent.maxx = fb->width - 1,
.extent.maxy = fb->height - 1,
};
}
VKAPI_ATTR void VKAPI_CALL
panvk_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo *pRenderPassBegin,
const VkSubpassBeginInfo *pSubpassBeginInfo)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(panvk_render_pass, pass, pRenderPassBegin->renderPass);
VK_FROM_HANDLE(vk_framebuffer, fb, pRenderPassBegin->framebuffer);
cmdbuf->state.pass = pass;
cmdbuf->state.subpass = pass->subpasses;
cmdbuf->state.framebuffer = fb;
cmdbuf->state.render_area = pRenderPassBegin->renderArea;
panvk_cmd_open_batch(cmdbuf);
assert(pRenderPassBegin->clearValueCount <= pass->attachment_count);
cmdbuf->state.clear =
vk_zalloc(&cmdbuf->vk.pool->alloc,
sizeof(*cmdbuf->state.clear) * pass->attachment_count, 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
panvk_cmd_prepare_clear_values(cmdbuf, pRenderPassBegin->pClearValues);
panvk_cmd_fb_info_init(cmdbuf);
panvk_cmd_fb_info_set_subpass(cmdbuf);
}
void
panvk_cmd_preload_fb_after_batch_split(struct panvk_cmd_buffer *cmdbuf)
{

View file

@ -1,224 +0,0 @@
/*
* Copyright © 2021 Collabora Ltd.
*
* Derived from tu_pass.c which is:
* Copyright © 2016 Red Hat.
* Copyright © 2016 Bas Nieuwenhuizen
* Copyright © 2015 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "panvk_private.h"
#include "vk_format.h"
#include "vk_util.h"
VKAPI_ATTR VkResult VKAPI_CALL
panvk_CreateRenderPass2(VkDevice _device,
const VkRenderPassCreateInfo2 *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkRenderPass *pRenderPass)
{
VK_FROM_HANDLE(panvk_device, device, _device);
struct panvk_render_pass *pass;
size_t size;
size_t attachments_offset;
VkRenderPassMultiviewCreateInfo *multiview_info = NULL;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2);
size = sizeof(*pass);
size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
attachments_offset = size;
size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
pass = vk_object_zalloc(&device->vk, pAllocator, size,
VK_OBJECT_TYPE_RENDER_PASS);
if (pass == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
pass->attachment_count = pCreateInfo->attachmentCount;
pass->subpass_count = pCreateInfo->subpassCount;
pass->attachments = (void *)pass + attachments_offset;
vk_foreach_struct_const(ext, pCreateInfo->pNext) {
switch (ext->sType) {
case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO:
multiview_info = (VkRenderPassMultiviewCreateInfo *)ext;
break;
default:
break;
}
}
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
struct panvk_render_pass_attachment *att = &pass->attachments[i];
att->format =
vk_format_to_pipe_format(pCreateInfo->pAttachments[i].format);
att->samples = pCreateInfo->pAttachments[i].samples;
att->load_op = pCreateInfo->pAttachments[i].loadOp;
att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
att->initial_layout = pCreateInfo->pAttachments[i].initialLayout;
att->final_layout = pCreateInfo->pAttachments[i].finalLayout;
att->store_op = pCreateInfo->pAttachments[i].storeOp;
att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
att->first_used_in_subpass = ~0;
}
uint32_t subpass_attachment_count = 0;
struct panvk_subpass_attachment *p;
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i];
subpass_attachment_count +=
desc->inputAttachmentCount + desc->colorAttachmentCount +
(desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
(desc->pDepthStencilAttachment != NULL);
}
if (subpass_attachment_count) {
pass->subpass_attachments = vk_alloc2(
&device->vk.alloc, pAllocator,
subpass_attachment_count * sizeof(struct panvk_subpass_attachment), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pass->subpass_attachments == NULL) {
vk_object_free(&device->vk, pAllocator, pass);
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
}
}
p = pass->subpass_attachments;
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i];
struct panvk_subpass *subpass = &pass->subpasses[i];
subpass->input_count = desc->inputAttachmentCount;
subpass->color_count = desc->colorAttachmentCount;
if (multiview_info)
subpass->view_mask = multiview_info->pViewMasks[i];
if (desc->inputAttachmentCount > 0) {
subpass->input_attachments = p;
p += desc->inputAttachmentCount;
for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
subpass->input_attachments[j] = (struct panvk_subpass_attachment){
.idx = desc->pInputAttachments[j].attachment,
.layout = desc->pInputAttachments[j].layout,
};
if (desc->pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
pass->attachments[desc->pInputAttachments[j].attachment]
.view_mask |= subpass->view_mask;
}
}
if (desc->colorAttachmentCount > 0) {
subpass->color_attachments = p;
p += desc->colorAttachmentCount;
for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
uint32_t idx = desc->pColorAttachments[j].attachment;
subpass->color_attachments[j] = (struct panvk_subpass_attachment){
.idx = idx,
.layout = desc->pColorAttachments[j].layout,
};
if (idx != VK_ATTACHMENT_UNUSED) {
pass->attachments[idx].view_mask |= subpass->view_mask;
if (pass->attachments[idx].first_used_in_subpass == ~0) {
pass->attachments[idx].first_used_in_subpass = i;
if (pass->attachments[idx].load_op ==
VK_ATTACHMENT_LOAD_OP_CLEAR)
subpass->color_attachments[j].clear = true;
else if (pass->attachments[idx].load_op ==
VK_ATTACHMENT_LOAD_OP_LOAD)
subpass->color_attachments[j].preload = true;
} else {
subpass->color_attachments[j].preload = true;
}
}
}
}
if (desc->pResolveAttachments) {
subpass->resolve_attachments = p;
p += desc->colorAttachmentCount;
for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
uint32_t idx = desc->pResolveAttachments[j].attachment;
subpass->resolve_attachments[j] = (struct panvk_subpass_attachment){
.idx = idx,
.layout = desc->pResolveAttachments[j].layout,
};
if (idx != VK_ATTACHMENT_UNUSED)
pass->attachments[idx].view_mask |= subpass->view_mask;
}
}
unsigned idx = desc->pDepthStencilAttachment
? desc->pDepthStencilAttachment->attachment
: VK_ATTACHMENT_UNUSED;
subpass->zs_attachment.idx = idx;
if (idx != VK_ATTACHMENT_UNUSED) {
subpass->zs_attachment.layout = desc->pDepthStencilAttachment->layout;
pass->attachments[idx].view_mask |= subpass->view_mask;
if (pass->attachments[idx].first_used_in_subpass == ~0) {
pass->attachments[idx].first_used_in_subpass = i;
if (pass->attachments[idx].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
subpass->zs_attachment.clear = true;
else if (pass->attachments[idx].load_op ==
VK_ATTACHMENT_LOAD_OP_LOAD)
subpass->zs_attachment.preload = true;
} else {
subpass->zs_attachment.preload = true;
}
}
}
*pRenderPass = panvk_render_pass_to_handle(pass);
return VK_SUCCESS;
}
VKAPI_ATTR void VKAPI_CALL
panvk_DestroyRenderPass(VkDevice _device, VkRenderPass _pass,
const VkAllocationCallbacks *pAllocator)
{
VK_FROM_HANDLE(panvk_device, device, _device);
VK_FROM_HANDLE(panvk_render_pass, pass, _pass);
if (!pass)
return;
vk_free2(&device->vk.alloc, pAllocator, pass->subpass_attachments);
vk_object_free(&device->vk, pAllocator, pass);
}
VKAPI_ATTR void VKAPI_CALL
panvk_GetRenderAreaGranularity(VkDevice _device, VkRenderPass renderPass,
VkExtent2D *pGranularity)
{
/* TODO: Return the actual tile size for the render pass? */
*pGranularity = (VkExtent2D){1, 1};
}

View file

@ -312,8 +312,11 @@ struct panvk_batch {
struct util_dynarray event_ops;
struct pan_jc jc;
struct {
const struct vk_framebuffer *info;
struct panfrost_ptr desc;
uint32_t bo_count;
/* One slot per color, two more slots for the depth/stencil buffers. */
struct pan_kmod_bo *bos[MAX_RTS + 2];
} fb;
struct {
struct pan_kmod_bo *src, *dst;
@ -757,15 +760,10 @@ struct panvk_cmd_state {
struct {
struct pan_fb_info info;
bool crc_valid[MAX_RTS];
uint32_t bo_count;
struct pan_kmod_bo *bos[MAX_RTS + 2];
} fb;
const struct panvk_render_pass *pass;
const struct panvk_subpass *subpass;
const struct vk_framebuffer *framebuffer;
VkRect2D render_area;
struct panvk_clear_value *clear;
mali_ptr vpd;
VkViewport viewport;
VkRect2D scissor;
@ -811,10 +809,6 @@ struct panvk_cmd_buffer {
struct panvk_batch *panvk_cmd_open_batch(struct panvk_cmd_buffer *cmdbuf);
void panvk_cmd_fb_info_set_subpass(struct panvk_cmd_buffer *cmdbuf);
void panvk_cmd_fb_info_init(struct panvk_cmd_buffer *cmdbuf);
void panvk_cmd_preload_fb_after_batch_split(struct panvk_cmd_buffer *cmdbuf);
struct panvk_event {
@ -992,63 +986,6 @@ struct panvk_buffer_view {
} descs;
};
struct panvk_attachment_info {
struct panvk_image_view *iview;
};
struct panvk_clear_value {
union {
uint32_t color[4];
struct {
float depth;
uint8_t stencil;
};
};
};
struct panvk_subpass_attachment {
uint32_t idx;
VkImageLayout layout;
bool clear;
bool preload;
};
struct panvk_subpass {
uint32_t input_count;
uint32_t color_count;
struct panvk_subpass_attachment *input_attachments;
uint8_t active_color_attachments;
struct panvk_subpass_attachment *color_attachments;
struct panvk_subpass_attachment *resolve_attachments;
struct panvk_subpass_attachment zs_attachment;
uint32_t view_mask;
};
struct panvk_render_pass_attachment {
VkAttachmentDescriptionFlags flags;
enum pipe_format format;
unsigned samples;
VkAttachmentLoadOp load_op;
VkAttachmentStoreOp store_op;
VkAttachmentLoadOp stencil_load_op;
VkAttachmentStoreOp stencil_store_op;
VkImageLayout initial_layout;
VkImageLayout final_layout;
unsigned view_mask;
unsigned first_used_in_subpass;
};
struct panvk_render_pass {
struct vk_object_base base;
uint32_t attachment_count;
uint32_t subpass_count;
struct panvk_subpass_attachment *subpass_attachments;
struct panvk_render_pass_attachment *attachments;
struct panvk_subpass subpasses[0];
};
VK_DEFINE_HANDLE_CASTS(panvk_cmd_buffer, vk.base, VkCommandBuffer,
VK_OBJECT_TYPE_COMMAND_BUFFER)
VK_DEFINE_HANDLE_CASTS(panvk_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE)
@ -1082,8 +1019,6 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_pipeline, base, VkPipeline,
VK_OBJECT_TYPE_PIPELINE)
VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_pipeline_layout, vk.base, VkPipelineLayout,
VK_OBJECT_TYPE_PIPELINE_LAYOUT)
VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_render_pass, base, VkRenderPass,
VK_OBJECT_TYPE_RENDER_PASS)
VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_sampler, vk.base, VkSampler,
VK_OBJECT_TYPE_SAMPLER)

View file

@ -158,32 +158,6 @@ panvk_per_arch(cmd_close_batch)(struct panvk_cmd_buffer *cmdbuf)
cmdbuf->state.batch = NULL;
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdNextSubpass2)(VkCommandBuffer commandBuffer,
const VkSubpassBeginInfo *pSubpassBeginInfo,
const VkSubpassEndInfo *pSubpassEndInfo)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
panvk_per_arch(cmd_close_batch)(cmdbuf);
cmdbuf->state.subpass++;
panvk_cmd_fb_info_set_subpass(cmdbuf);
panvk_cmd_open_batch(cmdbuf);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdNextSubpass)(VkCommandBuffer cmd, VkSubpassContents contents)
{
VkSubpassBeginInfo binfo = {.sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
.contents = contents};
VkSubpassEndInfo einfo = {
.sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
};
panvk_per_arch(CmdNextSubpass2)(cmd, &binfo, &einfo);
}
void
panvk_per_arch(cmd_alloc_fb_desc)(struct panvk_cmd_buffer *cmdbuf)
{
@ -195,7 +169,9 @@ panvk_per_arch(cmd_alloc_fb_desc)(struct panvk_cmd_buffer *cmdbuf)
const struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
bool has_zs_ext = fbinfo->zs.view.zs || fbinfo->zs.view.s;
batch->fb.info = cmdbuf->state.framebuffer;
batch->fb.bo_count = cmdbuf->state.fb.bo_count;
memcpy(batch->fb.bos, cmdbuf->state.fb.bos,
batch->fb.bo_count * sizeof(batch->fb.bos[0]));
batch->fb.desc = pan_pool_alloc_desc_aggregate(
&cmdbuf->desc_pool.base, PAN_DESC(FRAMEBUFFER),
PAN_DESC_ARRAY(has_zs_ext ? 1 : 0, ZS_CRC_EXTENSION),
@ -909,31 +885,6 @@ panvk_per_arch(EndCommandBuffer)(VkCommandBuffer commandBuffer)
return vk_command_buffer_end(&cmdbuf->vk);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdEndRenderPass2)(VkCommandBuffer commandBuffer,
const VkSubpassEndInfo *pSubpassEndInfo)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
panvk_per_arch(cmd_close_batch)(cmdbuf);
vk_free(&cmdbuf->vk.pool->alloc, cmdbuf->state.clear);
cmdbuf->state.batch = NULL;
cmdbuf->state.pass = NULL;
cmdbuf->state.subpass = NULL;
cmdbuf->state.framebuffer = NULL;
cmdbuf->state.clear = NULL;
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdEndRenderPass)(VkCommandBuffer cmd)
{
VkSubpassEndInfo einfo = {
.sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
};
panvk_per_arch(CmdEndRenderPass2)(cmd, &einfo);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdPipelineBarrier2)(VkCommandBuffer commandBuffer,
const VkDependencyInfo *pDependencyInfo)
@ -1020,7 +971,7 @@ panvk_per_arch(CmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent _event,
VK_FROM_HANDLE(panvk_event, event, _event);
/* vkCmdSetEvent cannot be called inside a render pass */
assert(cmdbuf->state.pass == NULL);
assert(cmdbuf->vk.render_pass == NULL);
panvk_add_set_event_operation(cmdbuf, event, PANVK_EVENT_OP_SET);
}
@ -1033,7 +984,7 @@ panvk_per_arch(CmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent _event,
VK_FROM_HANDLE(panvk_event, event, _event);
/* vkCmdResetEvent cannot be called inside a render pass */
assert(cmdbuf->state.pass == NULL);
assert(cmdbuf->vk.render_pass == NULL);
panvk_add_set_event_operation(cmdbuf, event, PANVK_EVENT_OP_RESET);
}
@ -1238,3 +1189,142 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x,
panvk_per_arch(cmd_close_batch)(cmdbuf);
desc_state->dirty = 0;
}
static void
panvk_cmd_begin_rendering_init_fbinfo(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.fb.info;
cmdbuf->state.fb.bo_count = 0;
memset(cmdbuf->state.fb.bos, 0, sizeof(cmdbuf->state.fb.bos));
memset(cmdbuf->state.fb.crc_valid, 0, sizeof(cmdbuf->state.fb.crc_valid));
*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 =
vk_image_mip_level_extent(&img->vk, iview->vk.base_mip_level);
fbinfo->width = MAX2(iview_size.width, fbinfo->width);
fbinfo->height = MAX2(iview_size.height, fbinfo->height);
cmdbuf->state.fb.bos[cmdbuf->state.fb.bo_count++] = img->bo;
fbinfo->rts[i].view = &iview->pview;
fbinfo->rts[i].crc_valid = &cmdbuf->state.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 (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 =
vk_image_mip_level_extent(&img->vk, iview->vk.base_mip_level);
fbinfo->width = MAX2(iview_size.width, fbinfo->width);
fbinfo->height = MAX2(iview_size.height, fbinfo->height);
cmdbuf->state.fb.bos[cmdbuf->state.fb.bo_count++] = img->bo;
fbinfo->zs.view.zs = &iview->pview;
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 (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 =
vk_image_mip_level_extent(&img->vk, iview->vk.base_mip_level);
fbinfo->width = MAX2(iview_size.width, fbinfo->width);
fbinfo->height = MAX2(iview_size.height, fbinfo->height);
cmdbuf->state.fb.bos[cmdbuf->state.fb.bo_count++] = img->bo;
fbinfo->zs.view.s =
iview && &iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL;
if (iview && 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;
}
}
/* We need the rendering area to be aligned on 32x32 section for tile buffer
* preloading to work correctly.
*/
fbinfo->width =
MIN2(fbinfo->width, ALIGN_POT(pRenderingInfo->renderArea.offset.x +
pRenderingInfo->renderArea.extent.width,
32));
fbinfo->height = MIN2(fbinfo->height,
ALIGN_POT(pRenderingInfo->renderArea.offset.y +
pRenderingInfo->renderArea.extent.height,
32));
assert(fbinfo->width && fbinfo->height);
fbinfo->extent.maxx = fbinfo->width - 1;
fbinfo->extent.maxy = fbinfo->height - 1;
}
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_fbinfo(cmdbuf, pRenderingInfo);
panvk_cmd_open_batch(cmdbuf);
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdEndRendering)(VkCommandBuffer commandBuffer)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
panvk_per_arch(cmd_close_batch)(cmdbuf);
cmdbuf->state.batch = NULL;
}

View file

@ -229,13 +229,12 @@ panvk_per_arch(queue_submit)(struct vk_queue *vk_queue,
list_for_each_entry(struct panvk_batch, batch, &cmdbuf->batches, node) {
/* FIXME: should be done at the batch level */
unsigned nr_bos =
panvk_pool_num_bos(&cmdbuf->desc_pool) +
panvk_pool_num_bos(&cmdbuf->varying_pool) +
panvk_pool_num_bos(&cmdbuf->tls_pool) +
(batch->fb.info ? batch->fb.info->attachment_count : 0) +
(batch->blit.src ? 1 : 0) + (batch->blit.dst ? 1 : 0) +
(batch->jc.first_tiler ? 1 : 0) + 1;
unsigned nr_bos = panvk_pool_num_bos(&cmdbuf->desc_pool) +
panvk_pool_num_bos(&cmdbuf->varying_pool) +
panvk_pool_num_bos(&cmdbuf->tls_pool) +
batch->fb.bo_count + (batch->blit.src ? 1 : 0) +
(batch->blit.dst ? 1 : 0) +
(batch->jc.first_tiler ? 1 : 0) + 1;
unsigned bo_idx = 0;
uint32_t bos[nr_bos];
@ -248,16 +247,8 @@ panvk_per_arch(queue_submit)(struct vk_queue *vk_queue,
panvk_pool_get_bo_handles(&cmdbuf->tls_pool, &bos[bo_idx]);
bo_idx += panvk_pool_num_bos(&cmdbuf->tls_pool);
if (batch->fb.info) {
for (unsigned i = 0; i < batch->fb.info->attachment_count; i++) {
VK_FROM_HANDLE(panvk_image_view, iview,
batch->fb.info->attachments[i]);
struct panvk_image *img =
container_of(iview->vk.image, struct panvk_image, vk);
bos[bo_idx++] = pan_kmod_bo_handle(img->bo);
}
}
for (unsigned i = 0; i < batch->fb.bo_count; i++)
bos[bo_idx++] = pan_kmod_bo_handle(batch->fb.bos[i]);
if (batch->blit.src)
bos[bo_idx++] = pan_kmod_bo_handle(batch->blit.src);

View file

@ -31,6 +31,7 @@
#include "panvk_vX_meta.h"
#include "vk_format.h"
#include "vk_render_pass.h"
static mali_ptr
panvk_meta_clear_color_attachment_shader(struct panvk_device *dev,
@ -251,8 +252,7 @@ panvk_meta_get_format_type(enum pipe_format format)
}
static void
panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf,
unsigned attachment, unsigned rt,
panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf, unsigned rt,
VkImageAspectFlags mask,
const VkClearValue *clear_value,
const VkClearRect *clear_rect)
@ -260,9 +260,7 @@ panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf,
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_meta *meta = &dev->meta;
struct panvk_batch *batch = cmdbuf->state.batch;
const struct panvk_render_pass *pass = cmdbuf->state.pass;
const struct panvk_render_pass_attachment *att =
&pass->attachments[attachment];
enum pipe_format pfmt = cmdbuf->state.fb.info.rts[rt].view->format;
unsigned minx = MAX2(clear_rect->rect.offset.x, 0);
unsigned miny = MAX2(clear_rect->rect.offset.y, 0);
unsigned maxx =
@ -284,7 +282,7 @@ panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf,
mali_ptr coordinates =
pan_pool_upload_aligned(&cmdbuf->desc_pool.base, rect, sizeof(rect), 64);
enum glsl_base_type base_type = panvk_meta_get_format_type(att->format);
enum glsl_base_type base_type = panvk_meta_get_format_type(pfmt);
mali_ptr tiler = batch->tiler.descs.gpu;
mali_ptr tsd = batch->tls.gpu;
@ -300,7 +298,7 @@ panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf,
sizeof(*clear_value), 16);
rsd = panvk_meta_clear_color_attachment_emit_rsd(
&cmdbuf->desc_pool.base, att->format, rt, shader_info, shader);
&cmdbuf->desc_pool.base, pfmt, rt, shader_info, shader);
} else {
rsd = panvk_meta_clear_zs_attachment_emit_rsd(
&cmdbuf->desc_pool.base, mask, clear_value->depthStencil);
@ -476,24 +474,24 @@ panvk_per_arch(CmdClearAttachments)(VkCommandBuffer commandBuffer,
const VkClearRect *pRects)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
const struct panvk_subpass *subpass = cmdbuf->state.subpass;
const struct vk_subpass *subpass =
&cmdbuf->vk.render_pass->subpasses[cmdbuf->vk.subpass_idx];
for (unsigned i = 0; i < attachmentCount; i++) {
for (unsigned j = 0; j < rectCount; j++) {
uint32_t attachment, rt = 0;
uint32_t attachment = VK_ATTACHMENT_UNUSED, rt = 0;
if (pAttachments[i].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
rt = pAttachments[i].colorAttachment;
attachment = subpass->color_attachments[rt].idx;
} else {
attachment = subpass->zs_attachment.idx;
attachment = subpass->color_attachments[rt].attachment;
} else if (subpass->depth_stencil_attachment) {
attachment = subpass->depth_stencil_attachment->attachment;
}
if (attachment == VK_ATTACHMENT_UNUSED)
continue;
panvk_meta_clear_attachment(cmdbuf, attachment, rt,
pAttachments[i].aspectMask,
panvk_meta_clear_attachment(cmdbuf, rt, pAttachments[i].aspectMask,
&pAttachments[i].clearValue, &pRects[j]);
}
}

View file

@ -39,6 +39,7 @@
#include "vk_blend.h"
#include "vk_format.h"
#include "vk_pipeline_cache.h"
#include "vk_render_pass.h"
#include "vk_util.h"
#include "panfrost/util/pan_lower_framebuffer.h"
@ -874,24 +875,24 @@ panvk_pipeline_builder_init_graphics(
} else {
builder->samples = create_info->pMultisampleState->rasterizationSamples;
const struct panvk_render_pass *pass =
panvk_render_pass_from_handle(create_info->renderPass);
const struct panvk_subpass *subpass =
&pass->subpasses[create_info->subpass];
VK_FROM_HANDLE(vk_render_pass, pass, create_info->renderPass);
const struct vk_subpass *subpass = &pass->subpasses[create_info->subpass];
builder->use_depth_stencil_attachment =
subpass->zs_attachment.idx != VK_ATTACHMENT_UNUSED;
subpass->depth_stencil_attachment &&
subpass->depth_stencil_attachment->attachment != VK_ATTACHMENT_UNUSED;
assert(subpass->color_count <=
create_info->pColorBlendState->attachmentCount);
builder->active_color_attachments = 0;
for (uint32_t i = 0; i < subpass->color_count; i++) {
uint32_t idx = subpass->color_attachments[i].idx;
uint32_t idx = subpass->color_attachments[i].attachment;
if (idx == VK_ATTACHMENT_UNUSED)
continue;
builder->active_color_attachments |= 1 << i;
builder->color_attachment_formats[i] = pass->attachments[idx].format;
builder->color_attachment_formats[i] =
vk_format_to_pipe_format(pass->attachments[idx].format);
}
}
}