}
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 panvk_framebuffer *fb = cmdbuf->state.framebuffer;
+ const struct panvk_clear_value *clears = cmdbuf->state.clear;
+ struct panvk_image_view *view;
+
+ 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;
+ view = idx != VK_ATTACHMENT_UNUSED ?
+ fb->attachments[idx].iview : NULL;
+ if (!view)
+ continue;
+ 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, view->pview.image->layout.nr_samples);
+ }
+
+ if (subpass->zs_attachment.idx != VK_ATTACHMENT_UNUSED) {
+ view = fb->attachments[subpass->zs_attachment.idx].iview;
+ const struct util_format_description *fdesc =
+ util_format_description(view->pview.format);
+
+ fbinfo->nr_samples =
+ MAX2(fbinfo->nr_samples, view->pview.image->layout.nr_samples);
+
+ 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].depth;
+ if (!fbinfo->zs.view.zs)
+ fbinfo->zs.view.s = &view->pview;
+ }
+ }
+}
+
+void
+panvk_cmd_fb_info_init(struct panvk_cmd_buffer *cmdbuf)
+{
+ struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
+ const struct panvk_framebuffer *fb = cmdbuf->state.framebuffer;
+
+ memset(cmdbuf->state.fb.crc_valid, 0, sizeof(cmdbuf->state.fb.crc_valid));
+
+ *fbinfo = (struct pan_fb_info) {
+ .width = fb->width,
+ .height = fb->height,
+ .extent.maxx = fb->width - 1,
+ .extent.maxy = fb->height - 1,
+ };
+}
+
+void
panvk_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo *pRenderPassBegin,
const VkSubpassBeginInfo *pSubpassBeginInfo)
sizeof(*cmdbuf->state.clear) *
pRenderPassBegin->clearValueCount, 8,
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
- assert(pRenderPassBegin->clearValueCount == pass->attachment_count);
panvk_cmd_prepare_clear_values(cmdbuf, pRenderPassBegin->pClearValues);
memset(&cmdbuf->state.compute, 0, sizeof(cmdbuf->state.compute));
+ panvk_cmd_fb_info_init(cmdbuf);
+ panvk_cmd_fb_info_set_subpass(cmdbuf);
}
void
}
void
+panvk_cmd_preload_fb_after_batch_split(struct panvk_cmd_buffer *cmdbuf)
+{
+ for (unsigned i = 0; i < cmdbuf->state.fb.info.rt_count; i++) {
+ if (cmdbuf->state.fb.info.rts[i].view) {
+ cmdbuf->state.fb.info.rts[i].clear = false;
+ cmdbuf->state.fb.info.rts[i].preload = true;
+ }
+ }
+
+ if (cmdbuf->state.fb.info.zs.view.zs) {
+ cmdbuf->state.fb.info.zs.clear.z = false;
+ cmdbuf->state.fb.info.zs.preload.z = true;
+ }
+
+ if (cmdbuf->state.fb.info.zs.view.s ||
+ (cmdbuf->state.fb.info.zs.view.zs &&
+ util_format_is_depth_and_stencil(cmdbuf->state.fb.info.zs.view.zs->format))) {
+ cmdbuf->state.fb.info.zs.clear.s = false;
+ cmdbuf->state.fb.info.zs.preload.s = true;
+ }
+}
+
+void
panvk_cmd_open_batch(struct panvk_cmd_buffer *cmdbuf)
{
assert(!cmdbuf->state.batch);
att->final_layout = pCreateInfo->pAttachments[i].finalLayout;
att->store_op = pCreateInfo->pAttachments[i].storeOp;
att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
- att->clear_subpass = ~0;
+ att->first_used_in_subpass = ~0;
}
uint32_t subpass_attachment_count = 0;
if (idx != VK_ATTACHMENT_UNUSED) {
pass->attachments[idx].view_mask |= subpass->view_mask;
- if (pass->attachments[idx].clear_subpass == ~0) {
- pass->attachments[idx].clear_subpass = i;
- subpass->color_attachments[j].clear = true;
+ 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 (idx != VK_ATTACHMENT_UNUSED) {
subpass->zs_attachment.layout = desc->pDepthStencilAttachment->layout;
pass->attachments[idx].view_mask |= subpass->view_mask;
- if (pass->attachments[idx].clear_subpass == ~0) {
- pass->attachments[idx].clear_subpass = i;
- subpass->zs_attachment.clear = true;
+
+ 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;
}
}
}
} s_front, s_back;
} zs;
+ struct {
+ struct pan_fb_info info;
+ bool crc_valid[MAX_RTS];
+ } fb;
+
const struct panvk_render_pass *pass;
const struct panvk_subpass *subpass;
const struct panvk_framebuffer *framebuffer;
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);
+
+void
panvk_pack_color(struct panvk_clear_value *out,
const VkClearColorValue *in,
enum pipe_format format);
uint32_t idx;
VkImageLayout layout;
bool clear;
+ bool preload;
};
struct panvk_subpass {
VkImageLayout initial_layout;
VkImageLayout final_layout;
unsigned view_mask;
- unsigned clear_subpass;
+ unsigned first_used_in_subpass;
};
struct panvk_render_pass {
list_addtail(&cmdbuf->state.batch->node, &cmdbuf->batches);
+ if (batch->scoreboard.first_tiler) {
+ struct panfrost_ptr preload_jobs[2];
+ unsigned num_preload_jobs =
+ GENX(pan_preload_fb)(&cmdbuf->desc_pool.base, &batch->scoreboard,
+ &cmdbuf->state.fb.info,
+ PAN_ARCH >= 6 ? batch->tls.gpu : batch->fb.desc.gpu,
+ PAN_ARCH >= 6 ? batch->tiler.descs.gpu : 0,
+ preload_jobs);
+ for (unsigned i = 0; i < num_preload_jobs; i++)
+ util_dynarray_append(&batch->jobs, void *, preload_jobs[i].cpu);
+ }
+
struct pan_tls_info tlsinfo = { 0 };
if (cmdbuf->state.pipeline) {
#endif
cmdbuf->state.batch->fb.desc.gpu |=
- panvk_per_arch(emit_fb)(cmdbuf->device,
- cmdbuf->state.batch,
- cmdbuf->state.subpass,
- cmdbuf->state.framebuffer,
- cmdbuf->state.clear,
- &tlsinfo, &cmdbuf->state.batch->tiler.ctx,
- fbd);
+ GENX(pan_emit_fbd)(pdev, &cmdbuf->state.fb.info, &tlsinfo,
+ &cmdbuf->state.batch->tiler.ctx, fbd);
#if PAN_ARCH <= 5
panvk_copy_fb_desc(cmdbuf, tmp_fbd);
panvk_per_arch(cmd_close_batch)(cmdbuf);
cmdbuf->state.subpass++;
+ panvk_cmd_fb_info_set_subpass(cmdbuf);
panvk_cmd_open_batch(cmdbuf);
memset(&cmdbuf->state.compute, 0, sizeof(cmdbuf->state.compute));
}
/* Tag the pointer */
batch->fb.desc.gpu |= tags;
+
+#if PAN_ARCH >= 6
+ memset(&cmdbuf->state.fb.info.bifrost.pre_post.dcds, 0,
+ sizeof(cmdbuf->state.fb.info.bifrost.pre_post.dcds));
+#endif
}
void
*/
if (batch->scoreboard.job_index >= (UINT16_MAX - 3)) {
panvk_per_arch(cmd_close_batch)(cmdbuf);
+ panvk_cmd_preload_fb_after_batch_split(cmdbuf);
panvk_cmd_open_batch(cmdbuf);
batch = cmdbuf->state.batch;
}
*/
if (cmdbuf->state.batch) {
panvk_per_arch(cmd_close_batch)(cmdbuf);
+ panvk_cmd_preload_fb_after_batch_split(cmdbuf);
panvk_cmd_open_batch(cmdbuf);
}
}
struct panvk_event_op,
op);
panvk_per_arch(cmd_close_batch)(cmdbuf);
+ panvk_cmd_preload_fb_after_batch_split(cmdbuf);
panvk_cmd_open_batch(cmdbuf);
}
}
if (cmdbuf->state.batch->fragment_job ||
cmdbuf->state.batch->scoreboard.first_job) {
panvk_per_arch(cmd_close_batch)(cmdbuf);
+ panvk_cmd_preload_fb_after_batch_split(cmdbuf);
panvk_cmd_open_batch(cmdbuf);
}
util_dynarray_append(&cmdbuf->state.batch->event_ops,
}
#endif
}
-
-unsigned
-panvk_per_arch(emit_fb)(const struct panvk_device *dev,
- const struct panvk_batch *batch,
- const struct panvk_subpass *subpass,
- const struct panvk_framebuffer *fb,
- const struct panvk_clear_value *clears,
- const struct pan_tls_info *tlsinfo,
- const struct pan_tiler_context *tilerctx,
- void *desc)
-{
- const struct panfrost_device *pdev = &dev->physical_device->pdev;
- struct panvk_image_view *view;
- bool crc_valid[8] = { false };
- struct pan_fb_info fbinfo = {
- .width = fb->width,
- .height = fb->height,
- .extent.maxx = fb->width - 1,
- .extent.maxy = fb->height - 1,
- .nr_samples = 1,
- };
-
- for (unsigned cb = 0; cb < subpass->color_count; cb++) {
- int idx = subpass->color_attachments[cb].idx;
- view = idx != VK_ATTACHMENT_UNUSED ?
- fb->attachments[idx].iview : NULL;
- if (!view)
- continue;
- fbinfo.rts[cb].view = &view->pview;
- fbinfo.rts[cb].clear = subpass->color_attachments[idx].clear;
- fbinfo.rts[cb].crc_valid = &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, view->pview.image->layout.nr_samples);
- }
-
- if (subpass->zs_attachment.idx != VK_ATTACHMENT_UNUSED) {
- view = fb->attachments[subpass->zs_attachment.idx].iview;
- const struct util_format_description *fdesc =
- util_format_description(view->pview.format);
-
- fbinfo.nr_samples =
- MAX2(fbinfo.nr_samples, view->pview.image->layout.nr_samples);
-
- 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_depth(fdesc)) {
- fbinfo.zs.clear.s = subpass->zs_attachment.clear;
- fbinfo.zs.clear_value.stencil = clears[subpass->zs_attachment.idx].depth;
- if (!fbinfo.zs.view.zs)
- fbinfo.zs.view.s = &view->pview;
- }
- }
-
- return GENX(pan_emit_fbd)(pdev, &fbinfo, tlsinfo, tilerctx, desc);
-}
panvk_per_arch(emit_tiler_context)(const struct panvk_device *dev,
unsigned width, unsigned height,
const struct panfrost_ptr *descs);
-
-unsigned
-panvk_per_arch(emit_fb)(const struct panvk_device *dev,
- const struct panvk_batch *batch,
- const struct panvk_subpass *subpass,
- const struct panvk_framebuffer *fb,
- const struct panvk_clear_value *clears,
- const struct pan_tls_info *tlsinfo,
- const struct pan_tiler_context *tilerctx,
- void *desc);