mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 08:40:11 +01:00
tc: add resolve resource to rp info
this allows non-winsys resolves to be optimized out Acked-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35477>
This commit is contained in:
parent
e2d40aab6f
commit
8933b3ed39
6 changed files with 105 additions and 20 deletions
|
|
@ -232,17 +232,21 @@ tc_batch_increment_renderpass_info(struct threaded_context *tc, unsigned batch_i
|
|||
/* copy the previous data in its entirety: this is still the same renderpass */
|
||||
if (tc->renderpass_info_recording) {
|
||||
tc_info[batch->renderpass_info_idx].info.data = tc->renderpass_info_recording->data;
|
||||
tc_info[batch->renderpass_info_idx].info.resolve = tc->renderpass_info_recording->resolve;
|
||||
tc->renderpass_info_recording->resolve = NULL;
|
||||
tc_batch_rp_info(tc->renderpass_info_recording)->next = &tc_info[batch->renderpass_info_idx];
|
||||
tc_info[batch->renderpass_info_idx].prev = tc_batch_rp_info(tc->renderpass_info_recording);
|
||||
/* guard against deadlock scenario */
|
||||
assert(&tc_batch_rp_info(tc->renderpass_info_recording)->next->info != tc->renderpass_info_recording);
|
||||
} else {
|
||||
tc_info[batch->renderpass_info_idx].info.data = 0;
|
||||
pipe_resource_reference(&tc_info[batch->renderpass_info_idx].info.resolve, NULL);
|
||||
tc_info[batch->renderpass_info_idx].prev = NULL;
|
||||
}
|
||||
} else {
|
||||
/* selectively copy: only the CSO metadata is copied, and a new framebuffer state will be added later */
|
||||
tc_info[batch->renderpass_info_idx].info.data = 0;
|
||||
pipe_resource_reference(&tc_info[batch->renderpass_info_idx].info.resolve, NULL);
|
||||
if (tc->renderpass_info_recording) {
|
||||
tc_info[batch->renderpass_info_idx].info.data16[2] = tc->renderpass_info_recording->data16[2];
|
||||
tc_batch_rp_info(tc->renderpass_info_recording)->next = NULL;
|
||||
|
|
@ -1477,6 +1481,9 @@ tc_set_framebuffer_state(struct pipe_context *_pipe,
|
|||
tc_set_resource_batch_usage_persistent(tc, tc->fb_resources[i], true);
|
||||
}
|
||||
tc->nr_cbufs = nr_cbufs;
|
||||
tc->fb_layers = util_framebuffer_get_num_layers(fb);
|
||||
tc->fb_width = fb->width;
|
||||
tc->fb_height = fb->height;
|
||||
if (tc->options.parse_renderpass_info) {
|
||||
/* store existing zsbuf data for possible persistence */
|
||||
uint8_t zsbuf = tc->renderpass_info_recording->has_draw ?
|
||||
|
|
@ -1500,7 +1507,9 @@ tc_set_framebuffer_state(struct pipe_context *_pipe,
|
|||
* just increment the index and keep using the existing info for recording
|
||||
*/
|
||||
tc->batch_slots[tc->next].renderpass_info_idx = 0;
|
||||
tc->renderpass_info_recording->has_resolve = false;
|
||||
}
|
||||
assert(!tc->renderpass_info_recording->resolve);
|
||||
tc->seen_fb_state = true;
|
||||
}
|
||||
/* ref for cmd */
|
||||
|
|
@ -4498,7 +4507,13 @@ tc_call_blit(struct pipe_context *pipe, void *call)
|
|||
return call_size(tc_blit_call);
|
||||
}
|
||||
|
||||
static void
|
||||
static uint16_t ALWAYS_INLINE
|
||||
tc_call_resolve(struct pipe_context *pipe, void *call)
|
||||
{
|
||||
return tc_call_blit(pipe, call);
|
||||
}
|
||||
|
||||
static struct tc_blit_call *
|
||||
tc_blit_enqueue(struct threaded_context *tc, const struct pipe_blit_info *info)
|
||||
{
|
||||
struct tc_blit_call *blit = tc_add_call(tc, TC_CALL_blit, tc_blit_call);
|
||||
|
|
@ -4508,6 +4523,7 @@ tc_blit_enqueue(struct threaded_context *tc, const struct pipe_blit_info *info)
|
|||
tc_set_resource_batch_usage(tc, info->src.resource);
|
||||
tc_set_resource_reference(&blit->info.src.resource, info->src.resource);
|
||||
memcpy(&blit->info, info, sizeof(*info));
|
||||
return blit;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -4518,29 +4534,62 @@ tc_blit(struct pipe_context *_pipe, const struct pipe_blit_info *info)
|
|||
/* filter out untracked non-resolves */
|
||||
if (!tc->options.parse_renderpass_info ||
|
||||
info->src.resource->nr_samples <= 1 ||
|
||||
info->dst.resource->nr_samples > 1) {
|
||||
info->dst.resource->nr_samples > 1 ||
|
||||
info->scissor_enable ||
|
||||
info->swizzle_enable ||
|
||||
info->alpha_blend ||
|
||||
info->src.resource->format != info->src.format ||
|
||||
info->dst.resource->format != info->dst.format ||
|
||||
info->src.format != info->dst.format ||
|
||||
info->src.box.width < 0 ||
|
||||
info->src.box.height < 0 ||
|
||||
info->src.box.depth < 0 ||
|
||||
info->dst.box.width < 0 ||
|
||||
info->dst.box.height < 0 ||
|
||||
info->dst.box.depth < 0 ||
|
||||
info->src.box.x != info->dst.box.x ||
|
||||
info->src.box.y != info->dst.box.y ||
|
||||
info->src.box.z != info->dst.box.z ||
|
||||
info->src.box.width != info->dst.box.width ||
|
||||
info->src.box.height != info->dst.box.height ||
|
||||
info->src.box.depth != info->dst.box.depth ||
|
||||
info->src.box.width != tc->fb_width ||
|
||||
info->src.box.height != tc->fb_height ||
|
||||
tc->renderpass_info_recording->ended ||
|
||||
(info->dst.resource->array_size && info->dst.resource->array_size != tc->fb_layers) ||
|
||||
(!tc->renderpass_info_recording->has_draw && !tc->renderpass_info_recording->cbuf_clear && !tc->renderpass_info_recording->zsbuf_clear)) {
|
||||
if (tc->options.parse_renderpass_info && tc->in_renderpass)
|
||||
tc_check_fb_access(tc, info->src.resource, info->dst.resource);
|
||||
tc_blit_enqueue(tc, info);
|
||||
return;
|
||||
}
|
||||
|
||||
struct pipe_resource *src = tc->nr_cbufs ? tc->fb_resources[0] : tc->fb_resources[PIPE_MAX_COLOR_BUFS];
|
||||
if (tc->fb_resolve == info->dst.resource) {
|
||||
#if TC_DEBUG >= 3
|
||||
tc_printf("WSI RESOLVE MERGE");
|
||||
#endif
|
||||
/* optimize out this blit entirely */
|
||||
tc->renderpass_info_recording->has_resolve = true;
|
||||
tc->renderpass_info_recording->ended = true;
|
||||
tc_signal_renderpass_info_ready(tc);
|
||||
return;
|
||||
}
|
||||
for (unsigned i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
|
||||
if (tc->fb_resources[i] == info->src.resource) {
|
||||
tc->renderpass_info_recording->has_resolve = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tc->options.parse_renderpass_info && tc->in_renderpass)
|
||||
} else if (src == info->src.resource &&
|
||||
(!tc->renderpass_info_recording->has_resolve ||
|
||||
tc->renderpass_info_recording->resolve == info->dst.resource)) {
|
||||
#if TC_DEBUG >= 3
|
||||
tc_printf("RESOLVE MERGE");
|
||||
#endif
|
||||
/* can only optimize out the first resolve */
|
||||
tc->renderpass_info_recording->has_resolve = true;
|
||||
pipe_resource_reference(&tc->renderpass_info_recording->resolve, info->dst.resource);
|
||||
tc_set_resource_batch_usage(tc, info->dst.resource);
|
||||
tc->renderpass_info_recording->ended = true;
|
||||
tc_signal_renderpass_info_ready(tc);
|
||||
} else if (tc->in_renderpass) {
|
||||
tc_check_fb_access(tc, info->src.resource, info->dst.resource);
|
||||
tc_blit_enqueue(tc, info);
|
||||
}
|
||||
struct tc_blit_call *blit = tc_blit_enqueue(tc, info);
|
||||
blit->base.call_id = TC_CALL_resolve;
|
||||
}
|
||||
|
||||
struct tc_generate_mipmap {
|
||||
|
|
|
|||
|
|
@ -440,7 +440,7 @@ struct tc_renderpass_info {
|
|||
bool zsbuf_invalidate : 1;
|
||||
/* whether a draw occurs */
|
||||
bool has_draw : 1;
|
||||
/* whether a framebuffer resolve occurs on cbuf[0] */
|
||||
/* whether a framebuffer resolve occurs on cbuf[0] or zsbuf */
|
||||
bool has_resolve : 1;
|
||||
/* whether queries are ended during this renderpass */
|
||||
bool has_query_ends : 1;
|
||||
|
|
@ -468,6 +468,8 @@ struct tc_renderpass_info {
|
|||
/* zsbuf fb info is in data8[3] & BITFIELD_MASK(4) */
|
||||
uint8_t data8[8];
|
||||
};
|
||||
/* only valid if has_resolve is true and the resolve member of pipe_framebuffer_state is NULL */
|
||||
struct pipe_resource *resolve;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
|
|
@ -640,6 +642,9 @@ struct threaded_context {
|
|||
unsigned max_images;
|
||||
unsigned max_samplers;
|
||||
unsigned nr_cbufs;
|
||||
unsigned fb_layers;
|
||||
uint16_t fb_width;
|
||||
uint16_t fb_height;
|
||||
|
||||
unsigned last, next, next_buf_list;
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ CALL(draw_vstate_single)
|
|||
CALL(draw_vstate_multi)
|
||||
CALL(launch_grid)
|
||||
CALL(blit)
|
||||
CALL(resolve)
|
||||
CALL(generate_mipmap)
|
||||
CALL(invalidate_resource)
|
||||
CALL(clear_render_target)
|
||||
|
|
|
|||
|
|
@ -330,6 +330,18 @@ zink_blit(struct pipe_context *pctx,
|
|||
struct zink_resource *use_src = src;
|
||||
struct zink_resource *dst = zink_resource(info->dst.resource);
|
||||
bool needs_present_readback = false;
|
||||
|
||||
if (ctx->awaiting_resolve && ctx->in_rp && ctx->dynamic_fb.tc_info.has_resolve) {
|
||||
struct pipe_resource *resolve = ctx->fb_state.resolve;
|
||||
if (!resolve)
|
||||
resolve = ctx->dynamic_fb.tc_info.resolve;
|
||||
if (resolve == info->dst.resource) {
|
||||
zink_batch_no_rp_safe(ctx);
|
||||
ctx->awaiting_resolve = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (zink_is_swapchain(dst)) {
|
||||
if (!zink_kopper_acquire(ctx, dst, UINT64_MAX))
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ update_tc_info(struct zink_context *ctx)
|
|||
const struct tc_renderpass_info *info = threaded_context_get_renderpass_info(ctx->tc);
|
||||
ctx->rp_changed |= ctx->dynamic_fb.tc_info.data != info->data;
|
||||
ctx->dynamic_fb.tc_info.data = info->data;
|
||||
ctx->dynamic_fb.tc_info.resolve = info->resolve;
|
||||
ctx->awaiting_resolve = ctx->dynamic_fb.tc_info.has_resolve;
|
||||
} else {
|
||||
struct tc_renderpass_info info = ctx->dynamic_fb.tc_info;
|
||||
bool zsbuf_used = !ctx->zsbuf_unused;
|
||||
|
|
@ -3204,22 +3206,37 @@ begin_rendering(struct zink_context *ctx, bool check_msaa_expand)
|
|||
ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS + 1].resolveMode = 0;
|
||||
}
|
||||
}
|
||||
if (ctx->fb_state.resolve && use_tc_info && ctx->dynamic_fb.tc_info.has_resolve) {
|
||||
if (use_tc_info && ctx->dynamic_fb.tc_info.has_resolve) {
|
||||
struct zink_resource *res = zink_resource(ctx->fb_state.resolve);
|
||||
zink_surface_resolve_init(screen, res, ctx->fb_state.resolve->format);
|
||||
if (!res)
|
||||
res = zink_resource(ctx->dynamic_fb.tc_info.resolve);
|
||||
assert(res);
|
||||
zink_batch_resource_usage_set(ctx->bs, res, true, false);
|
||||
bool is_depth = util_format_is_depth_or_stencil(res->base.b.format);
|
||||
enum pipe_format format = res->base.b.format;
|
||||
if (!ctx->fb_state.resolve)
|
||||
format = is_depth ? ctx->fb_state.zsbuf.format : ctx->fb_state.cbufs[0].format;
|
||||
zink_surface_resolve_init(screen, res, format);
|
||||
struct zink_surface *surf = zink_surface(res->surface);
|
||||
if (zink_is_swapchain(res)) {
|
||||
if (!zink_kopper_acquire(ctx, res, UINT64_MAX))
|
||||
return 0;
|
||||
zink_surface_swapchain_update(ctx, surf);
|
||||
}
|
||||
zink_batch_resource_usage_set(ctx->bs, res, true, false);
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
VkImageLayout layout = is_depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
if (screen->driver_workarounds.general_layout)
|
||||
layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
unsigned idx = util_format_is_depth_or_stencil(res->base.b.format) ? PIPE_MAX_COLOR_BUFS : 0;
|
||||
screen->image_barrier(ctx, res, layout, 0, 0);
|
||||
res->obj->unordered_read = res->obj->unordered_write = false;
|
||||
ctx->dynamic_fb.attachments[0].resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
|
||||
ctx->dynamic_fb.attachments[0].resolveImageLayout = zink_resource(surf->base.texture)->layout;
|
||||
ctx->dynamic_fb.attachments[0].resolveImageView = surf->image_view;
|
||||
ctx->dynamic_fb.attachments[idx].resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
|
||||
ctx->dynamic_fb.attachments[idx].resolveImageLayout = zink_resource(surf->base.texture)->layout;
|
||||
ctx->dynamic_fb.attachments[idx].resolveImageView = surf->image_view;
|
||||
if (idx == PIPE_MAX_COLOR_BUFS) {
|
||||
ctx->dynamic_fb.attachments[idx + 1].resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
|
||||
ctx->dynamic_fb.attachments[idx + 1].resolveImageLayout = zink_resource(surf->base.texture)->layout;
|
||||
ctx->dynamic_fb.attachments[idx + 1].resolveImageView = surf->image_view;
|
||||
}
|
||||
}
|
||||
ctx->zsbuf_unused = !zsbuf_used;
|
||||
assert(ctx->fb_state.width >= ctx->dynamic_fb.info.renderArea.extent.width);
|
||||
|
|
|
|||
|
|
@ -1768,6 +1768,7 @@ struct zink_context {
|
|||
struct set rendering_state_cache[6]; //[util_logbase2_ceil(msrtss samplecount)]
|
||||
struct zink_resource *swapchain;
|
||||
VkExtent2D swapchain_size;
|
||||
bool awaiting_resolve; //from tc info
|
||||
bool in_rp; //renderpass is currently active
|
||||
bool rp_changed; //force renderpass restart
|
||||
bool rp_layout_changed; //renderpass changed, maybe restart
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue