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:

committed by
Marge Bot

parent
2ee9487ad7
commit
692e0dfe27
@@ -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)
|
||||||
|
@@ -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:
|
||||||
*
|
*
|
||||||
|
@@ -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);
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user