v3dv: implement VK_KHR_imageless_framebuffer

Reviewed-by: Juan A. Suarez <jasuarez@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14704>
This commit is contained in:
Iago Toral Quiroga 2022-01-24 13:38:08 +01:00 committed by Marge Bot
parent 2ee9487ad7
commit 692e0dfe27
7 changed files with 82 additions and 23 deletions

View File

@ -452,7 +452,7 @@ Vulkan 1.2 -- all DONE: anv, vn
VK_KHR_draw_indirect_count DONE (anv, lvp, radv, tu, vn)
VK_KHR_driver_properties DONE (anv, lvp, radv, v3dv, vn)
VK_KHR_image_format_list DONE (anv, lvp, radv, tu, v3dv, vn)
VK_KHR_imageless_framebuffer DONE (anv, lvp, radv, tu, vn)
VK_KHR_imageless_framebuffer DONE (anv, lvp, radv, tu, v3dv, vn)
VK_KHR_sampler_mirror_clamp_to_edge DONE (anv, lvp, radv, tu, v3dv, vn)
VK_KHR_separate_depth_stencil_layouts DONE (anv, lvp, radv, vn, tu)
VK_KHR_shader_atomic_int64 DONE (anv/gen9+, lvp, radv, vn)

View File

@ -941,8 +941,6 @@ cmd_buffer_subpass_handle_pending_resolves(struct v3dv_cmd_buffer *cmd_buffer)
if (!subpass->resolve_attachments)
return;
struct v3dv_framebuffer *fb = cmd_buffer->state.framebuffer;
/* At this point we have already ended the current subpass and now we are
* about to emit vkCmdResolveImage calls to get the resolves we can't handle
* handle in the subpass RCL.
@ -977,8 +975,10 @@ cmd_buffer_subpass_handle_pending_resolves(struct v3dv_cmd_buffer *cmd_buffer)
if (dst_attachment_idx == VK_ATTACHMENT_UNUSED)
continue;
struct v3dv_image_view *src_iview = fb->attachments[src_attachment_idx];
struct v3dv_image_view *dst_iview = fb->attachments[dst_attachment_idx];
struct v3dv_image_view *src_iview =
cmd_buffer->state.attachments[src_attachment_idx].image_view;
struct v3dv_image_view *dst_iview =
cmd_buffer->state.attachments[dst_attachment_idx].image_view;
VkImageResolve2KHR region = {
.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,
@ -1241,6 +1241,31 @@ cmd_buffer_state_set_clear_values(struct v3dv_cmd_buffer *cmd_buffer,
}
}
static void
cmd_buffer_state_set_attachments(struct v3dv_cmd_buffer *cmd_buffer,
const VkRenderPassBeginInfo *pRenderPassBegin)
{
V3DV_FROM_HANDLE(v3dv_render_pass, pass, pRenderPassBegin->renderPass);
V3DV_FROM_HANDLE(v3dv_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
const VkRenderPassAttachmentBeginInfoKHR *attach_begin =
vk_find_struct_const(pRenderPassBegin, RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR);
struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
for (uint32_t i = 0; i < pass->attachment_count; i++) {
if (attach_begin && attach_begin->attachmentCount != 0) {
state->attachments[i].image_view =
v3dv_image_view_from_handle(attach_begin->pAttachments[i]);
} else if (framebuffer) {
state->attachments[i].image_view = framebuffer->attachments[i];
} else {
assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY);
state->attachments[i].image_view = NULL;
}
}
}
static void
cmd_buffer_init_render_pass_attachment_state(struct v3dv_cmd_buffer *cmd_buffer,
const VkRenderPassBeginInfo *pRenderPassBegin)
@ -1248,6 +1273,8 @@ cmd_buffer_init_render_pass_attachment_state(struct v3dv_cmd_buffer *cmd_buffer,
cmd_buffer_state_set_clear_values(cmd_buffer,
pRenderPassBegin->clearValueCount,
pRenderPassBegin->pClearValues);
cmd_buffer_state_set_attachments(cmd_buffer, pRenderPassBegin);
}
static void
@ -1476,7 +1503,7 @@ cmd_buffer_subpass_create_job(struct v3dv_cmd_buffer *cmd_buffer,
uint8_t internal_bpp;
bool msaa;
v3dv_X(job->device, framebuffer_compute_internal_bpp_msaa)
(framebuffer, subpass, &internal_bpp, &msaa);
(framebuffer, state->attachments, subpass, &internal_bpp, &msaa);
/* From the Vulkan spec:
*

View File

@ -133,6 +133,7 @@ get_device_extensions(const struct v3dv_physical_device *device,
.KHR_external_semaphore_fd = true,
.KHR_get_memory_requirements2 = true,
.KHR_image_format_list = true,
.KHR_imageless_framebuffer = true,
.KHR_relaxed_block_layout = true,
.KHR_maintenance1 = true,
.KHR_maintenance2 = true,
@ -1123,6 +1124,13 @@ v3dv_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR: {
VkPhysicalDeviceImagelessFramebufferFeatures *features =
(VkPhysicalDeviceImagelessFramebufferFeatures *)ext;
features->imagelessFramebuffer = true;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {
VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *features =
(VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *)ext;
@ -2503,13 +2511,25 @@ v3dv_CreateFramebuffer(VkDevice _device,
framebuffer->layers = pCreateInfo->layers;
framebuffer->has_edge_padding = true;
const VkFramebufferAttachmentsCreateInfo *imageless =
vk_find_struct_const(pCreateInfo->pNext,
FRAMEBUFFER_ATTACHMENTS_CREATE_INFO);
framebuffer->attachment_count = pCreateInfo->attachmentCount;
framebuffer->color_attachment_count = 0;
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
framebuffer->attachments[i] =
v3dv_image_view_from_handle(pCreateInfo->pAttachments[i]);
if (framebuffer->attachments[i]->vk.aspects & VK_IMAGE_ASPECT_COLOR_BIT)
framebuffer->color_attachment_count++;
for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {
if (!imageless) {
framebuffer->attachments[i] =
v3dv_image_view_from_handle(pCreateInfo->pAttachments[i]);
if (framebuffer->attachments[i]->vk.aspects & VK_IMAGE_ASPECT_COLOR_BIT)
framebuffer->color_attachment_count++;
} else {
assert(i < imageless->attachmentImageInfoCount);
if (imageless->pAttachmentImageInfos[i].usage &
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
framebuffer->color_attachment_count++;
}
}
}
*pFramebuffer = v3dv_framebuffer_to_handle(framebuffer);

View File

@ -765,6 +765,11 @@ struct v3dv_framebuffer {
uint32_t attachment_count;
uint32_t color_attachment_count;
/* Notice that elements in 'attachments' will be NULL if the framebuffer
* was created imageless. The driver is expected to access attachment info
* from the command buffer state instead.
*/
struct v3dv_image_view *attachments[0];
};
@ -835,6 +840,11 @@ struct v3dv_cmd_buffer_attachment_state {
/* The hardware clear value */
union v3dv_clear_value clear_value;
/* The underlying image view (from the framebuffer or, if imageless
* framebuffer is used, from VkRenderPassAttachmentBeginInfo.
*/
struct v3dv_image_view *image_view;
};
struct v3dv_viewport_state {

View File

@ -200,7 +200,6 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer,
uint32_t layer)
{
const struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
const struct v3dv_framebuffer *framebuffer = state->framebuffer;
const struct v3dv_render_pass *pass = state->pass;
const struct v3dv_subpass *subpass = &pass->subpasses[state->subpass_idx];
@ -242,7 +241,8 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer,
first_subpass,
attachment->desc.loadOp);
if (needs_load) {
struct v3dv_image_view *iview = framebuffer->attachments[attachment_idx];
struct v3dv_image_view *iview =
state->attachments[attachment_idx].image_view;
cmd_buffer_render_pass_emit_load(cmd_buffer, cl, iview,
layer, RENDER_TARGET_0 + i);
}
@ -274,7 +274,7 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer,
if (needs_depth_load || needs_stencil_load) {
struct v3dv_image_view *iview =
framebuffer->attachments[ds_attachment_idx];
state->attachments[ds_attachment_idx].image_view;
/* From the Vulkan spec:
*
* "When an image view of a depth/stencil image is used as a
@ -305,7 +305,7 @@ cmd_buffer_render_pass_emit_store(struct v3dv_cmd_buffer *cmd_buffer,
bool is_multisample_resolve)
{
const struct v3dv_image_view *iview =
cmd_buffer->state.framebuffer->attachments[attachment_idx];
cmd_buffer->state.attachments[attachment_idx].image_view;
const struct v3dv_image *image = (struct v3dv_image *) iview->vk.image;
const struct v3d_resource_slice *slice =
&image->slices[iview->vk.base_mip_level];
@ -803,7 +803,7 @@ v3dX(cmd_buffer_emit_render_pass_rcl)(struct v3dv_cmd_buffer *cmd_buffer)
if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
const struct v3dv_image_view *iview =
framebuffer->attachments[ds_attachment_idx];
state->attachments[ds_attachment_idx].image_view;
config.internal_depth_type = iview->internal_type;
set_rcl_early_z_config(job,
@ -875,7 +875,7 @@ v3dX(cmd_buffer_emit_render_pass_rcl)(struct v3dv_cmd_buffer *cmd_buffer)
continue;
struct v3dv_image_view *iview =
state->framebuffer->attachments[attachment_idx];
state->attachments[attachment_idx].image_view;
const struct v3dv_image *image = (struct v3dv_image *) iview->vk.image;
const struct v3d_resource_slice *slice =
@ -2292,9 +2292,9 @@ v3dX(cmd_buffer_render_pass_setup_render_target)(struct v3dv_cmd_buffer *cmd_buf
if (attachment_idx == VK_ATTACHMENT_UNUSED)
return;
const struct v3dv_framebuffer *framebuffer = state->framebuffer;
assert(attachment_idx < framebuffer->attachment_count);
struct v3dv_image_view *iview = framebuffer->attachments[attachment_idx];
assert(attachment_idx < state->framebuffer->attachment_count &&
attachment_idx < state->attachment_alloc_count);
struct v3dv_image_view *iview = state->attachments[attachment_idx].image_view;
assert(iview->vk.aspects & VK_IMAGE_ASPECT_COLOR_BIT);
*rt_bpp = iview->internal_bpp;

View File

@ -257,6 +257,7 @@ v3dX(pack_sampler_state)(struct v3dv_sampler *sampler,
void
v3dX(framebuffer_compute_internal_bpp_msaa)(
const struct v3dv_framebuffer *framebuffer,
const struct v3dv_cmd_buffer_attachment_state *attachments,
const struct v3dv_subpass *subpass,
uint8_t *max_bpp,
bool *msaa)
@ -271,7 +272,7 @@ v3dX(framebuffer_compute_internal_bpp_msaa)(
if (att_idx == VK_ATTACHMENT_UNUSED)
continue;
const struct v3dv_image_view *att = framebuffer->attachments[att_idx];
const struct v3dv_image_view *att = attachments[att_idx].image_view;
assert(att);
if (att->vk.aspects & VK_IMAGE_ASPECT_COLOR_BIT)
@ -283,7 +284,7 @@ v3dX(framebuffer_compute_internal_bpp_msaa)(
if (!*msaa && subpass->ds_attachment.attachment != VK_ATTACHMENT_UNUSED) {
const struct v3dv_image_view *att =
framebuffer->attachments[subpass->ds_attachment.attachment];
attachments[subpass->ds_attachment.attachment].image_view;
assert(att);
if (att->vk.image->samples > VK_SAMPLE_COUNT_1_BIT)
@ -295,7 +296,7 @@ v3dX(framebuffer_compute_internal_bpp_msaa)(
assert(framebuffer->attachment_count <= 4);
for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {
const struct v3dv_image_view *att = framebuffer->attachments[i];
const struct v3dv_image_view *att = attachments[i].image_view;
assert(att);
if (att->vk.aspects & VK_IMAGE_ASPECT_COLOR_BIT)

View File

@ -138,6 +138,7 @@ v3dX(pack_sampler_state)(struct v3dv_sampler *sampler,
void
v3dX(framebuffer_compute_internal_bpp_msaa)(const struct v3dv_framebuffer *framebuffer,
const struct v3dv_cmd_buffer_attachment_state *attachments,
const struct v3dv_subpass *subpass,
uint8_t *max_bpp, bool *msaa);