diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index c5d78c14aa3..390fd150453 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -66,7 +66,9 @@ struct lvp_render_attachment { VkResolveModeFlags resolve_mode; struct lvp_image_view *resolve_imgv; VkAttachmentLoadOp load_op; + VkAttachmentStoreOp store_op; VkClearValue clear_value; + bool read_only; }; struct rendering_state { @@ -91,6 +93,7 @@ struct rendering_state { bool ib_dirty; bool sample_mask_dirty; bool min_samples_dirty; + bool poison_mem; struct pipe_draw_indirect_info indirect_info; struct pipe_draw_info info; @@ -1794,7 +1797,7 @@ att_needs_replicate(const struct rendering_state *state, const struct lvp_image_ } static void render_att_init(struct lvp_render_attachment* att, - const VkRenderingAttachmentInfo *vk_att) + const VkRenderingAttachmentInfo *vk_att, bool poison_mem, bool stencil) { if (vk_att == NULL || vk_att->imageView == VK_NULL_HANDLE) { *att = (struct lvp_render_attachment) { @@ -1806,8 +1809,26 @@ static void render_att_init(struct lvp_render_attachment* att, *att = (struct lvp_render_attachment) { .imgv = lvp_image_view_from_handle(vk_att->imageView), .load_op = vk_att->loadOp, + .store_op = vk_att->storeOp, .clear_value = vk_att->clearValue, }; + if (util_format_is_depth_or_stencil(att->imgv->pformat)) { + if (stencil) + att->read_only = vk_att->imageLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL || + vk_att->imageLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL; + else + att->read_only = vk_att->imageLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL || + vk_att->imageLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL; + } + if (poison_mem && !att->read_only && att->load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE) { + att->load_op = VK_ATTACHMENT_LOAD_OP_CLEAR; + if (util_format_is_depth_or_stencil(att->imgv->pformat)) { + att->clear_value.depthStencil.depth = 0.12351251; + att->clear_value.depthStencil.stencil = rand() % UINT8_MAX; + } else { + memset(att->clear_value.color.uint32, rand() % UINT8_MAX, sizeof(att->clear_value.color.uint32)); + } + } if (vk_att->resolveImageView && vk_att->resolveMode) { att->resolve_imgv = lvp_image_view_from_handle(vk_att->resolveImageView); @@ -1847,7 +1868,7 @@ static void handle_begin_rendering(struct vk_cmd_queue_entry *cmd, state->color_att_count = info->colorAttachmentCount; state->color_att = realloc(state->color_att, sizeof(*state->color_att) * state->color_att_count); for (unsigned i = 0; i < info->colorAttachmentCount; i++) { - render_att_init(&state->color_att[i], &info->pColorAttachments[i]); + render_att_init(&state->color_att[i], &info->pColorAttachments[i], state->poison_mem, false); if (state->color_att[i].imgv) { struct lvp_image_view *imgv = state->color_att[i].imgv; add_img_view_surface(state, imgv, @@ -1864,8 +1885,8 @@ static void handle_begin_rendering(struct vk_cmd_queue_entry *cmd, } } - render_att_init(&state->depth_att, info->pDepthAttachment); - render_att_init(&state->stencil_att, info->pStencilAttachment); + render_att_init(&state->depth_att, info->pDepthAttachment, state->poison_mem, false); + render_att_init(&state->stencil_att, info->pStencilAttachment, state->poison_mem, true); if (state->depth_att.imgv || state->stencil_att.imgv) { assert(state->depth_att.imgv == NULL || state->stencil_att.imgv == NULL || @@ -1907,8 +1928,55 @@ static void handle_begin_rendering(struct vk_cmd_queue_entry *cmd, static void handle_end_rendering(struct vk_cmd_queue_entry *cmd, struct rendering_state *state) { - if (!state->suspending) - render_resolve(state); + if (state->suspending) + return; + render_resolve(state); + if (!state->poison_mem) + return; + union pipe_color_union color_clear_val; + memset(color_clear_val.ui, rand() % UINT8_MAX, sizeof(color_clear_val.ui)); + for (unsigned i = 0; i < state->framebuffer.nr_cbufs; i++) { + if (state->color_att[i].imgv && state->color_att[i].store_op == VK_ATTACHMENT_STORE_OP_DONT_CARE) { + if (state->info.view_mask) { + u_foreach_bit(i, state->info.view_mask) + clear_attachment_layers(state, state->color_att[i].imgv, &state->render_area, + i, 1, 0, 0, 0, &color_clear_val); + } else { + state->pctx->clear_render_target(state->pctx, + state->color_att[i].imgv->surface, + &color_clear_val, + state->render_area.offset.x, + state->render_area.offset.y, + state->render_area.extent.width, + state->render_area.extent.height, + false); + } + } + } + uint32_t ds_clear_flags = 0; + if (state->depth_att.imgv && !state->depth_att.read_only && state->depth_att.store_op == VK_ATTACHMENT_STORE_OP_DONT_CARE) + ds_clear_flags |= PIPE_CLEAR_DEPTH; + if (state->stencil_att.imgv && !state->stencil_att.read_only && state->stencil_att.store_op == VK_ATTACHMENT_STORE_OP_DONT_CARE) + ds_clear_flags |= PIPE_CLEAR_STENCIL; + double dclear_val = 0.2389234; + uint32_t sclear_val = rand() % UINT8_MAX; + if (ds_clear_flags) { + if (state->info.view_mask) { + u_foreach_bit(i, state->info.view_mask) + clear_attachment_layers(state, state->ds_imgv, &state->render_area, + i, 1, ds_clear_flags, dclear_val, sclear_val, NULL); + } else { + state->pctx->clear_depth_stencil(state->pctx, + state->ds_imgv->surface, + ds_clear_flags, + dclear_val, sclear_val, + state->render_area.offset.x, + state->render_area.offset.y, + state->render_area.extent.width, + state->render_area.extent.height, + false); + } + } } static void handle_draw(struct vk_cmd_queue_entry *cmd, @@ -4341,6 +4409,7 @@ VkResult lvp_execute_cmds(struct lvp_device *device, state->sample_mask_dirty = true; state->min_samples_dirty = true; state->sample_mask = UINT32_MAX; + state->poison_mem = device->poison_mem; for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) { for (unsigned i = 0; i < ARRAY_SIZE(state->cso_ss_ptr[s]); i++) state->cso_ss_ptr[s][i] = &state->ss[s][i];