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:
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_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)
|
||||
|
|
|
@ -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:
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue