lavapipe: VK_KHR_dynamic_rendering

this is a conformant implementation

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13627>
This commit is contained in:
Mike Blumenkrantz 2021-10-04 14:56:31 -04:00 committed by Marge Bot
parent dd71cc8947
commit 8a6160a354
3 changed files with 196 additions and 4 deletions

View File

@ -92,6 +92,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported =
.KHR_device_group = true,
.KHR_draw_indirect_count = true,
.KHR_driver_properties = true,
.KHR_dynamic_rendering = true,
.KHR_external_fence = true,
.KHR_external_memory = true,
#ifdef PIPE_MEMORY_FD
@ -666,6 +667,11 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2(
features->primitiveTopologyPatchListRestart = true;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR: {
VkPhysicalDeviceDynamicRenderingFeaturesKHR *features = (VkPhysicalDeviceDynamicRenderingFeaturesKHR *)ext;
features->dynamicRendering = VK_TRUE;
break;
}
default:
break;
}

View File

@ -1805,8 +1805,171 @@ static void handle_begin_render_pass2(struct vk_cmd_queue_entry *cmd,
begin_render_pass(cmd->u.begin_render_pass2.render_pass_begin, state);
}
static void handle_end_render_pass2(struct vk_cmd_queue_entry *cmd,
struct rendering_state *state)
static VkAttachmentLoadOp
get_load_op(VkAttachmentLoadOp op, bool resuming)
{
if (!resuming)
return op;
if (op == VK_ATTACHMENT_LOAD_OP_CLEAR)
return VK_ATTACHMENT_LOAD_OP_LOAD;
return op;
}
static void handle_begin_rendering(struct vk_cmd_queue_entry *cmd,
struct rendering_state *state)
{
const VkRenderingInfoKHR *info = cmd->u.begin_rendering_khr.rendering_info;
bool resuming = (info->flags & VK_RENDERING_RESUMING_BIT_KHR) == VK_RENDERING_RESUMING_BIT_KHR;
bool suspending = (info->flags & VK_RENDERING_SUSPENDING_BIT_KHR) == VK_RENDERING_SUSPENDING_BIT_KHR;
assert(!state->pass);
state->vk_framebuffer = NULL;
state->render_area = info->renderArea;
unsigned num_attachments = info->colorAttachmentCount + (info->pDepthAttachment || info->pStencilAttachment);
unsigned i, color_resolves = 0;
for (i = 0; i < info->colorAttachmentCount; i++) {
if (info->pColorAttachments[i].resolveImageView)
color_resolves++;
}
bool zresolve = info->pDepthAttachment && info->pDepthAttachment->resolveImageView;
bool sresolve = info->pStencilAttachment && info->pStencilAttachment->resolveImageView;
unsigned num_resolves = color_resolves + (zresolve || sresolve);
unsigned attachment_count = num_attachments + num_resolves;
state->imageless_views = realloc(state->imageless_views, sizeof(*state->imageless_views) * attachment_count);
state->render_area = info->renderArea;
state->framebuffer.width = info->renderArea.offset.x + info->renderArea.extent.width;
state->framebuffer.height = info->renderArea.offset.y + info->renderArea.extent.height;
state->framebuffer.layers = info->layerCount;
if (state->num_pending_aspects < attachment_count) {
state->pending_clear_aspects = realloc(state->pending_clear_aspects, sizeof(VkImageAspectFlags) * attachment_count);
state->cleared_views = realloc(state->cleared_views, sizeof(uint32_t) * attachment_count);
state->num_pending_aspects = attachment_count;
}
/* [lvp_subpass] [attachment_count * lvp_render_pass_attachment] [attachment_count * lvp_render_pass_attachment*] */
size_t size = sizeof(struct lvp_subpass) + attachment_count * (sizeof(void*) + sizeof(struct lvp_render_pass_attachment));
size_t attachment_offset = sizeof(struct lvp_subpass);
size_t attachment_ref_offset = attachment_offset + attachment_count * sizeof(struct lvp_render_pass_attachment);
struct lvp_subpass *subpass = calloc(1, size);
subpass->color_count = info->colorAttachmentCount;
bool has_ds = !!info->pDepthAttachment + !!info->pStencilAttachment;
state->attachments = realloc(state->attachments, sizeof(*state->attachments) * attachment_count);
struct lvp_render_pass_attachment *attachments = (void*)((uint8_t*)subpass + attachment_offset);
struct lvp_render_pass_attachment *resolve_attachments = num_resolves ? &attachments[subpass->color_count + has_ds] : NULL;
struct lvp_render_pass_attachment **attachment_refs = (void*)((uint8_t*)subpass + attachment_ref_offset);
struct lvp_render_pass_attachment **resolve_attachment_refs = num_resolves ? &attachment_refs[subpass->color_count + has_ds] : NULL;
subpass->view_mask = info->viewMask;
subpass->has_color_resolve = color_resolves > 0;
if (info->colorAttachmentCount)
subpass->color_attachments = attachment_refs;
if (has_ds)
subpass->depth_stencil_attachment = &attachment_refs[info->colorAttachmentCount];
if (color_resolves)
subpass->resolve_attachments = resolve_attachment_refs;
if (zresolve || sresolve)
subpass->ds_resolve_attachment = &resolve_attachment_refs[color_resolves];
unsigned resolve_idx = 0;
for (i = 0; i < info->colorAttachmentCount; i++) {
if (!info->pColorAttachments[i].imageView)
continue;
struct lvp_render_pass_attachment *att = &attachments[i];
att->attachment = i;
att->load_op = get_load_op(info->pColorAttachments[i].loadOp, resuming);
if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
state->attachments[i].pending_clear_aspects = VK_IMAGE_ASPECT_COLOR_BIT;
state->attachments[i].clear_value = info->pColorAttachments[i].clearValue;
} else
state->attachments[i].pending_clear_aspects = 0;
state->pending_clear_aspects[i] = state->attachments[i].pending_clear_aspects;
state->cleared_views[i] = 0;
state->imageless_views[i] = lvp_image_view_from_handle(info->pColorAttachments[i].imageView);
att->format = state->imageless_views[i]->format;
att->samples = state->imageless_views[i]->image->bo->nr_samples;
attachment_refs[i] = att;
if (!suspending && info->pColorAttachments[i].resolveImageView) {
struct lvp_render_pass_attachment *resolve_att = &resolve_attachments[resolve_idx];
resolve_att->attachment = num_attachments + resolve_idx;
resolve_att->load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
state->imageless_views[num_attachments + resolve_idx] = lvp_image_view_from_handle(info->pColorAttachments[i].resolveImageView);
resolve_att->format = state->imageless_views[num_attachments + resolve_idx]->format;
resolve_att->samples = state->imageless_views[num_attachments + resolve_idx]->image->bo->nr_samples;
resolve_attachment_refs[resolve_idx] = resolve_att;
resolve_idx++;
}
}
if (info->pDepthAttachment && info->pDepthAttachment->imageView) {
struct lvp_render_pass_attachment *att = &attachments[i];
att->attachment = i;
att->load_op = get_load_op(info->pDepthAttachment->loadOp, resuming);
att->stencil_load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
state->attachments[i].pending_clear_aspects = VK_IMAGE_ASPECT_DEPTH_BIT;
state->attachments[i].clear_value = info->pDepthAttachment->clearValue;
} else
state->attachments[i].pending_clear_aspects = 0;
state->pending_clear_aspects[i] = state->attachments[i].pending_clear_aspects;
state->cleared_views[i] = 0;
state->imageless_views[i] = lvp_image_view_from_handle(info->pDepthAttachment->imageView);
att->format = state->imageless_views[i]->format;
att->samples = state->imageless_views[i]->image->bo->nr_samples;
attachment_refs[i] = att;
if (!suspending && info->pDepthAttachment->resolveImageView) {
struct lvp_render_pass_attachment *resolve_att = &resolve_attachments[resolve_idx];
resolve_att->attachment = num_attachments + resolve_idx;
resolve_att->load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
state->imageless_views[num_attachments + resolve_idx] = lvp_image_view_from_handle(info->pDepthAttachment->resolveImageView);
resolve_att->format = state->imageless_views[num_attachments + resolve_idx]->format;
resolve_att->samples = state->imageless_views[num_attachments + resolve_idx]->image->bo->nr_samples;
resolve_attachment_refs[resolve_idx] = resolve_att;
}
}
if (info->pStencilAttachment && info->pStencilAttachment->imageView) {
struct lvp_render_pass_attachment *att = &attachments[i];
att->attachment = i;
if (!info->pDepthAttachment)
att->load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
att->stencil_load_op = get_load_op(info->pStencilAttachment->loadOp, resuming);
if (!info->pDepthAttachment)
state->attachments[i].pending_clear_aspects = 0;
if (att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
state->attachments[i].pending_clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
state->attachments[i].clear_value.depthStencil.stencil = info->pStencilAttachment->clearValue.depthStencil.stencil;
}
state->pending_clear_aspects[i] |= state->attachments[i].pending_clear_aspects;
state->cleared_views[i] = 0;
state->imageless_views[i] = lvp_image_view_from_handle(info->pStencilAttachment->imageView);
att->format = state->imageless_views[i]->format;
att->samples = state->imageless_views[i]->image->bo->nr_samples;
attachment_refs[i] = att;
if (!suspending && info->pStencilAttachment->resolveImageView) {
struct lvp_render_pass_attachment *resolve_att = &resolve_attachments[resolve_idx];
resolve_att->attachment = num_attachments + resolve_idx;
resolve_att->load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
state->imageless_views[num_attachments + resolve_idx] = lvp_image_view_from_handle(info->pStencilAttachment->resolveImageView);
resolve_att->format = state->imageless_views[num_attachments + resolve_idx]->format;
resolve_att->samples = state->imageless_views[num_attachments + resolve_idx]->image->bo->nr_samples;
resolve_attachment_refs[resolve_idx] = resolve_att;
}
}
begin_render_subpass(state, subpass);
}
static void
end_rendering(struct rendering_state *state)
{
state->pctx->flush(state->pctx, NULL, 0);
@ -1815,6 +1978,20 @@ static void handle_end_render_pass2(struct vk_cmd_queue_entry *cmd,
free(state->attachments);
state->attachments = NULL;
state->pass = NULL;
}
static void handle_end_rendering(struct vk_cmd_queue_entry *cmd,
struct rendering_state *state)
{
end_rendering(state);
free(state->subpass);
state->subpass = NULL;
}
static void handle_end_render_pass2(struct vk_cmd_queue_entry *cmd,
struct rendering_state *state)
{
end_rendering(state);
state->subpass = NULL;
}
@ -3909,6 +4086,12 @@ static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
case VK_CMD_SET_COLOR_WRITE_ENABLE_EXT:
handle_set_color_write_enable(cmd, state);
break;
case VK_CMD_BEGIN_RENDERING_KHR:
handle_begin_rendering(cmd, state);
break;
case VK_CMD_END_RENDERING_KHR:
handle_end_rendering(cmd, state);
break;
case VK_CMD_SET_DEVICE_MASK:
/* no-op */
break;

View File

@ -279,6 +279,7 @@ deep_copy_graphics_create_info(void *mem_ctx,
VkPipelineVertexInputStateCreateInfo *vertex_input;
VkPipelineRasterizationStateCreateInfo *rasterization_state;
LVP_FROM_HANDLE(lvp_render_pass, pass, src->renderPass);
const VkPipelineRenderingCreateInfoKHR *rp_info = vk_find_struct_const(src->pNext, PIPELINE_RENDERING_CREATE_INFO_KHR);
dst->sType = src->sType;
dst->pNext = NULL;
@ -367,7 +368,8 @@ deep_copy_graphics_create_info(void *mem_ctx,
dst->pMultisampleState = NULL;
/* pDepthStencilState */
if (src->pDepthStencilState && !rasterization_disabled && pass->has_zs_attachment) {
if (src->pDepthStencilState && !rasterization_disabled &&
(pass ? pass->has_zs_attachment : (rp_info->depthAttachmentFormat || rp_info->stencilAttachmentFormat))) {
LVP_PIPELINE_DUP(dst->pDepthStencilState,
src->pDepthStencilState,
VkPipelineDepthStencilStateCreateInfo,
@ -376,7 +378,8 @@ deep_copy_graphics_create_info(void *mem_ctx,
dst->pDepthStencilState = NULL;
/* pColorBlendState */
if (src->pColorBlendState && !rasterization_disabled && pass->has_color_attachment) {
if (src->pColorBlendState && !rasterization_disabled &&
(pass ? pass->has_color_attachment : rp_info->colorAttachmentCount)) {
VkPipelineColorBlendStateCreateInfo* cb_state;
cb_state = ralloc(mem_ctx, VkPipelineColorBlendStateCreateInfo);