From: Iago Toral Quiroga Date: Tue, 21 Apr 2020 12:01:35 +0000 (+0200) Subject: v3dv: meta operations can happen outside a render pass X-Git-Tag: upstream/21.0.0~3999 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=689bac310fddf74148ae9fb6f02648f3d57bebff;p=platform%2Fupstream%2Fmesa.git v3dv: meta operations can happen outside a render pass We were asserting that we had a valid subpass index, but we can have meta operations that run outside a render pass, such as for blitting. If we allow this, then we also need to account for the fact that pipelines can be bound outside a render pass too. Part-of: --- diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 8a8783f..7707a7e 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -2798,86 +2798,84 @@ emit_occlusion_query(struct v3dv_cmd_buffer *cmd_buffer) cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_OCCLUSION_QUERY; } -/* This stores command buffer state for the current subpass that we are - * about to interrupt to emit a meta pass. +/* This stores command buffer state that we might be about to stomp for + * a meta operation. */ void v3dv_cmd_buffer_meta_state_push(struct v3dv_cmd_buffer *cmd_buffer) { struct v3dv_cmd_buffer_state *state = &cmd_buffer->state; - assert(state->subpass_idx != -1); - state->meta.pipeline = v3dv_pipeline_to_handle(state->pipeline); - state->meta.framebuffer = v3dv_framebuffer_to_handle(state->framebuffer); - state->meta.pass = v3dv_render_pass_to_handle(state->pass); - state->meta.subpass_idx = state->subpass_idx; - - const uint32_t attachment_state_item_size = - sizeof(struct v3dv_cmd_buffer_attachment_state); - const uint32_t attachment_state_total_size = - attachment_state_item_size * state->attachment_count; - if (state->meta.attachment_alloc_count < state->attachment_count) { - if (state->meta.attachment_alloc_count > 0) - vk_free(&cmd_buffer->device->alloc, state->meta.attachments); - - state->meta.attachments = vk_zalloc(&cmd_buffer->device->alloc, - attachment_state_total_size, 8, - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); - state->meta.attachment_alloc_count = state->attachment_count; - } - state->meta.attachment_count = state->attachment_count; - memcpy(state->meta.attachments, state->attachments, - attachment_state_total_size); - - state->meta.tile_aligned_render_area = state->tile_aligned_render_area; - memcpy(&state->meta.render_area, &state->render_area, sizeof(VkRect2D)); + if (state->subpass_idx != -1) { + state->meta.subpass_idx = state->subpass_idx; + state->meta.framebuffer = v3dv_framebuffer_to_handle(state->framebuffer); + state->meta.pass = v3dv_render_pass_to_handle(state->pass); + + const uint32_t attachment_state_item_size = + sizeof(struct v3dv_cmd_buffer_attachment_state); + const uint32_t attachment_state_total_size = + attachment_state_item_size * state->attachment_count; + if (state->meta.attachment_alloc_count < state->attachment_count) { + if (state->meta.attachment_alloc_count > 0) + vk_free(&cmd_buffer->device->alloc, state->meta.attachments); + + state->meta.attachments = vk_zalloc(&cmd_buffer->device->alloc, + attachment_state_total_size, 8, + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + state->meta.attachment_alloc_count = state->attachment_count; + } + state->meta.attachment_count = state->attachment_count; + memcpy(state->meta.attachments, state->attachments, + attachment_state_total_size); + + state->meta.tile_aligned_render_area = state->tile_aligned_render_area; + memcpy(&state->meta.render_area, &state->render_area, sizeof(VkRect2D)); + } + state->meta.pipeline = v3dv_pipeline_to_handle(state->pipeline); if (state->meta.pipeline) memcpy(&state->meta.dynamic, &state->dynamic, sizeof(state->dynamic)); } -/* This resstores command buffer state for a subpass that we interrupted to - * emit a meta pass. +/* This restores command buffer state after a meta operation */ void v3dv_cmd_buffer_meta_state_pop(struct v3dv_cmd_buffer *cmd_buffer, uint32_t dirty_dynamic_state) { struct v3dv_cmd_buffer_state *state = &cmd_buffer->state; - assert(state->meta.subpass_idx != -1); - state->pass = v3dv_render_pass_from_handle(state->meta.pass); - state->framebuffer = v3dv_framebuffer_from_handle(state->meta.framebuffer); + if (state->meta.subpass_idx != -1) { + state->pass = v3dv_render_pass_from_handle(state->meta.pass); + state->framebuffer = v3dv_framebuffer_from_handle(state->meta.framebuffer); - assert(state->meta.attachment_count <= state->attachment_count); - const uint32_t attachment_state_item_size = - sizeof(struct v3dv_cmd_buffer_attachment_state); - const uint32_t attachment_state_total_size = - attachment_state_item_size * state->meta.attachment_count; - state->attachment_count = state->meta.attachment_count; - memcpy(state->attachments, state->meta.attachments, - attachment_state_total_size); + assert(state->meta.attachment_count <= state->attachment_count); + const uint32_t attachment_state_item_size = + sizeof(struct v3dv_cmd_buffer_attachment_state); + const uint32_t attachment_state_total_size = + attachment_state_item_size * state->meta.attachment_count; + state->attachment_count = state->meta.attachment_count; + memcpy(state->attachments, state->meta.attachments, + attachment_state_total_size); - state->tile_aligned_render_area = state->meta.tile_aligned_render_area; - memcpy(&state->render_area, &state->meta.render_area, sizeof(VkRect2D)); + state->tile_aligned_render_area = state->meta.tile_aligned_render_area; + memcpy(&state->render_area, &state->meta.render_area, sizeof(VkRect2D)); - struct v3dv_job *job = v3dv_cmd_buffer_subpass_resume(cmd_buffer, state->meta.subpass_idx); - if (job) { - if (state->meta.pipeline != VK_NULL_HANDLE) { - v3dv_CmdBindPipeline(v3dv_cmd_buffer_to_handle(cmd_buffer), - VK_PIPELINE_BIND_POINT_GRAPHICS, - state->meta.pipeline); - memcpy(&state->dynamic, &state->meta.dynamic, sizeof(state->dynamic)); - state->dirty |= dirty_dynamic_state; - } else { - state->pipeline = VK_NULL_HANDLE; - } } else { - state->pipeline = VK_NULL_HANDLE; state->subpass_idx = -1; } + if (state->meta.pipeline != VK_NULL_HANDLE) { + v3dv_CmdBindPipeline(v3dv_cmd_buffer_to_handle(cmd_buffer), + VK_PIPELINE_BIND_POINT_GRAPHICS, + state->meta.pipeline); + memcpy(&state->dynamic, &state->meta.dynamic, sizeof(state->dynamic)); + state->dirty |= dirty_dynamic_state; + } else { + state->pipeline = VK_NULL_HANDLE; + } + state->meta.pipeline = VK_NULL_HANDLE; state->meta.framebuffer = VK_NULL_HANDLE; state->meta.pass = VK_NULL_HANDLE;