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_draw_indirect_count DONE (anv, lvp, radv, tu, vn)
VK_KHR_driver_properties DONE (anv, lvp, radv, v3dv, 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_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_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_separate_depth_stencil_layouts DONE (anv, lvp, radv, vn, tu)
VK_KHR_shader_atomic_int64 DONE (anv/gen9+, lvp, radv, vn) 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) if (!subpass->resolve_attachments)
return; return;
struct v3dv_framebuffer *fb = cmd_buffer->state.framebuffer;
/* At this point we have already ended the current subpass and now we are /* 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 * about to emit vkCmdResolveImage calls to get the resolves we can't handle
* handle in the subpass RCL. * 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) if (dst_attachment_idx == VK_ATTACHMENT_UNUSED)
continue; continue;
struct v3dv_image_view *src_iview = fb->attachments[src_attachment_idx]; struct v3dv_image_view *src_iview =
struct v3dv_image_view *dst_iview = fb->attachments[dst_attachment_idx]; 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 = { VkImageResolve2KHR region = {
.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR, .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 static void
cmd_buffer_init_render_pass_attachment_state(struct v3dv_cmd_buffer *cmd_buffer, cmd_buffer_init_render_pass_attachment_state(struct v3dv_cmd_buffer *cmd_buffer,
const VkRenderPassBeginInfo *pRenderPassBegin) 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, cmd_buffer_state_set_clear_values(cmd_buffer,
pRenderPassBegin->clearValueCount, pRenderPassBegin->clearValueCount,
pRenderPassBegin->pClearValues); pRenderPassBegin->pClearValues);
cmd_buffer_state_set_attachments(cmd_buffer, pRenderPassBegin);
} }
static void static void
@@ -1476,7 +1503,7 @@ cmd_buffer_subpass_create_job(struct v3dv_cmd_buffer *cmd_buffer,
uint8_t internal_bpp; uint8_t internal_bpp;
bool msaa; bool msaa;
v3dv_X(job->device, framebuffer_compute_internal_bpp_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: /* 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_external_semaphore_fd = true,
.KHR_get_memory_requirements2 = true, .KHR_get_memory_requirements2 = true,
.KHR_image_format_list = true, .KHR_image_format_list = true,
.KHR_imageless_framebuffer = true,
.KHR_relaxed_block_layout = true, .KHR_relaxed_block_layout = true,
.KHR_maintenance1 = true, .KHR_maintenance1 = true,
.KHR_maintenance2 = true, .KHR_maintenance2 = true,
@@ -1123,6 +1124,13 @@ v3dv_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
break; 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: { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {
VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *features = VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *features =
(VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *)ext; (VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *)ext;
@@ -2503,13 +2511,25 @@ v3dv_CreateFramebuffer(VkDevice _device,
framebuffer->layers = pCreateInfo->layers; framebuffer->layers = pCreateInfo->layers;
framebuffer->has_edge_padding = true; framebuffer->has_edge_padding = true;
const VkFramebufferAttachmentsCreateInfo *imageless =
vk_find_struct_const(pCreateInfo->pNext,
FRAMEBUFFER_ATTACHMENTS_CREATE_INFO);
framebuffer->attachment_count = pCreateInfo->attachmentCount; framebuffer->attachment_count = pCreateInfo->attachmentCount;
framebuffer->color_attachment_count = 0; framebuffer->color_attachment_count = 0;
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {
if (!imageless) {
framebuffer->attachments[i] = framebuffer->attachments[i] =
v3dv_image_view_from_handle(pCreateInfo->pAttachments[i]); v3dv_image_view_from_handle(pCreateInfo->pAttachments[i]);
if (framebuffer->attachments[i]->vk.aspects & VK_IMAGE_ASPECT_COLOR_BIT) if (framebuffer->attachments[i]->vk.aspects & VK_IMAGE_ASPECT_COLOR_BIT)
framebuffer->color_attachment_count++; 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); *pFramebuffer = v3dv_framebuffer_to_handle(framebuffer);

View File

@@ -765,6 +765,11 @@ struct v3dv_framebuffer {
uint32_t attachment_count; uint32_t attachment_count;
uint32_t color_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]; struct v3dv_image_view *attachments[0];
}; };
@@ -835,6 +840,11 @@ struct v3dv_cmd_buffer_attachment_state {
/* The hardware clear value */ /* The hardware clear value */
union v3dv_clear_value 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 { 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) uint32_t layer)
{ {
const struct v3dv_cmd_buffer_state *state = &cmd_buffer->state; 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_render_pass *pass = state->pass;
const struct v3dv_subpass *subpass = &pass->subpasses[state->subpass_idx]; 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, first_subpass,
attachment->desc.loadOp); attachment->desc.loadOp);
if (needs_load) { 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, cmd_buffer_render_pass_emit_load(cmd_buffer, cl, iview,
layer, RENDER_TARGET_0 + i); 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) { if (needs_depth_load || needs_stencil_load) {
struct v3dv_image_view *iview = struct v3dv_image_view *iview =
framebuffer->attachments[ds_attachment_idx]; state->attachments[ds_attachment_idx].image_view;
/* From the Vulkan spec: /* From the Vulkan spec:
* *
* "When an image view of a depth/stencil image is used as a * "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) bool is_multisample_resolve)
{ {
const struct v3dv_image_view *iview = 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 v3dv_image *image = (struct v3dv_image *) iview->vk.image;
const struct v3d_resource_slice *slice = const struct v3d_resource_slice *slice =
&image->slices[iview->vk.base_mip_level]; &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) { if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
const struct v3dv_image_view *iview = 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; config.internal_depth_type = iview->internal_type;
set_rcl_early_z_config(job, set_rcl_early_z_config(job,
@@ -875,7 +875,7 @@ v3dX(cmd_buffer_emit_render_pass_rcl)(struct v3dv_cmd_buffer *cmd_buffer)
continue; continue;
struct v3dv_image_view *iview = 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 v3dv_image *image = (struct v3dv_image *) iview->vk.image;
const struct v3d_resource_slice *slice = 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) if (attachment_idx == VK_ATTACHMENT_UNUSED)
return; return;
const struct v3dv_framebuffer *framebuffer = state->framebuffer; assert(attachment_idx < state->framebuffer->attachment_count &&
assert(attachment_idx < framebuffer->attachment_count); attachment_idx < state->attachment_alloc_count);
struct v3dv_image_view *iview = framebuffer->attachments[attachment_idx]; struct v3dv_image_view *iview = state->attachments[attachment_idx].image_view;
assert(iview->vk.aspects & VK_IMAGE_ASPECT_COLOR_BIT); assert(iview->vk.aspects & VK_IMAGE_ASPECT_COLOR_BIT);
*rt_bpp = iview->internal_bpp; *rt_bpp = iview->internal_bpp;

View File

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

View File

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