vulkan/render_pass: Pass sample locations to barriers
This is required for depth/stencil images created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT. Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16953>
This commit is contained in:
parent
6216c59dbb
commit
7e11cdc77a
|
@ -46,6 +46,7 @@ struct vk_render_pass;
|
||||||
struct vk_attachment_view_state {
|
struct vk_attachment_view_state {
|
||||||
VkImageLayout layout;
|
VkImageLayout layout;
|
||||||
VkImageLayout stencil_layout;
|
VkImageLayout stencil_layout;
|
||||||
|
const VkSampleLocationsInfoEXT *sample_locations;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vk_attachment_state {
|
struct vk_attachment_state {
|
||||||
|
@ -130,6 +131,8 @@ struct vk_command_buffer {
|
||||||
/* This uses the same trick as STACK_ARRAY */
|
/* This uses the same trick as STACK_ARRAY */
|
||||||
struct vk_attachment_state *attachments;
|
struct vk_attachment_state *attachments;
|
||||||
struct vk_attachment_state _attachments[8];
|
struct vk_attachment_state _attachments[8];
|
||||||
|
|
||||||
|
VkRenderPassSampleLocationsBeginInfoEXT *pass_sample_locations;
|
||||||
};
|
};
|
||||||
|
|
||||||
VK_DEFINE_HANDLE_CASTS(vk_command_buffer, base, VkCommandBuffer,
|
VK_DEFINE_HANDLE_CASTS(vk_command_buffer, base, VkCommandBuffer,
|
||||||
|
|
|
@ -980,6 +980,103 @@ vk_common_GetRenderAreaGranularity(VkDevice device,
|
||||||
*pGranularity = (VkExtent2D) { 1, 1 };
|
*pGranularity = (VkExtent2D) { 1, 1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VkRenderPassSampleLocationsBeginInfoEXT *
|
||||||
|
clone_rp_sample_locations(const VkRenderPassSampleLocationsBeginInfoEXT *loc)
|
||||||
|
{
|
||||||
|
uint32_t sl_count = 0;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < loc->attachmentInitialSampleLocationsCount; i++) {
|
||||||
|
const VkAttachmentSampleLocationsEXT *att_sl_in =
|
||||||
|
&loc->pAttachmentInitialSampleLocations[i];
|
||||||
|
sl_count += att_sl_in->sampleLocationsInfo.sampleLocationsCount;
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < loc->postSubpassSampleLocationsCount; i++) {
|
||||||
|
const VkSubpassSampleLocationsEXT *sp_sl_in =
|
||||||
|
&loc->pPostSubpassSampleLocations[i];
|
||||||
|
sl_count += sp_sl_in->sampleLocationsInfo.sampleLocationsCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
VK_MULTIALLOC(ma);
|
||||||
|
VK_MULTIALLOC_DECL(&ma, VkRenderPassSampleLocationsBeginInfoEXT, new_loc, 1);
|
||||||
|
VK_MULTIALLOC_DECL(&ma, VkAttachmentSampleLocationsEXT, new_att_sl,
|
||||||
|
loc->attachmentInitialSampleLocationsCount);
|
||||||
|
VK_MULTIALLOC_DECL(&ma, VkSubpassSampleLocationsEXT, new_sp_sl,
|
||||||
|
loc->postSubpassSampleLocationsCount);
|
||||||
|
VK_MULTIALLOC_DECL(&ma, VkSampleLocationEXT, sl, sl_count);
|
||||||
|
if (!vk_multialloc_alloc(&ma, vk_default_allocator(),
|
||||||
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
VkSampleLocationEXT *next_sl = sl;
|
||||||
|
for (uint32_t i = 0; i < loc->attachmentInitialSampleLocationsCount; i++) {
|
||||||
|
const VkAttachmentSampleLocationsEXT *att_sl_in =
|
||||||
|
&loc->pAttachmentInitialSampleLocations[i];
|
||||||
|
const VkSampleLocationsInfoEXT *sli_in = &att_sl_in->sampleLocationsInfo;
|
||||||
|
|
||||||
|
typed_memcpy(next_sl, sli_in->pSampleLocations,
|
||||||
|
sli_in->sampleLocationsCount);
|
||||||
|
|
||||||
|
new_att_sl[i] = (VkAttachmentSampleLocationsEXT) {
|
||||||
|
.attachmentIndex = att_sl_in->attachmentIndex,
|
||||||
|
.sampleLocationsInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,
|
||||||
|
.sampleLocationsPerPixel = sli_in->sampleLocationsPerPixel,
|
||||||
|
.sampleLocationGridSize = sli_in->sampleLocationGridSize,
|
||||||
|
.sampleLocationsCount = sli_in->sampleLocationsCount,
|
||||||
|
.pSampleLocations = next_sl,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
next_sl += sli_in->sampleLocationsCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < loc->postSubpassSampleLocationsCount; i++) {
|
||||||
|
const VkSubpassSampleLocationsEXT *sp_sl_in =
|
||||||
|
&loc->pPostSubpassSampleLocations[i];
|
||||||
|
const VkSampleLocationsInfoEXT *sli_in = &sp_sl_in->sampleLocationsInfo;
|
||||||
|
|
||||||
|
typed_memcpy(next_sl, sli_in->pSampleLocations,
|
||||||
|
sli_in->sampleLocationsCount);
|
||||||
|
|
||||||
|
new_sp_sl[i] = (VkSubpassSampleLocationsEXT) {
|
||||||
|
.subpassIndex = sp_sl_in->subpassIndex,
|
||||||
|
.sampleLocationsInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,
|
||||||
|
.sampleLocationsPerPixel = sli_in->sampleLocationsPerPixel,
|
||||||
|
.sampleLocationGridSize = sli_in->sampleLocationGridSize,
|
||||||
|
.sampleLocationsCount = sli_in->sampleLocationsCount,
|
||||||
|
.pSampleLocations = next_sl,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
next_sl += sli_in->sampleLocationsCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(next_sl == sl + sl_count);
|
||||||
|
|
||||||
|
*new_loc = (VkRenderPassSampleLocationsBeginInfoEXT) {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT,
|
||||||
|
.attachmentInitialSampleLocationsCount = loc->attachmentInitialSampleLocationsCount,
|
||||||
|
.pAttachmentInitialSampleLocations = new_att_sl,
|
||||||
|
.postSubpassSampleLocationsCount = loc->postSubpassSampleLocationsCount,
|
||||||
|
.pPostSubpassSampleLocations = new_sp_sl,
|
||||||
|
};
|
||||||
|
|
||||||
|
return new_loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const VkSampleLocationsInfoEXT *
|
||||||
|
get_subpass_sample_locations(const VkRenderPassSampleLocationsBeginInfoEXT *loc,
|
||||||
|
uint32_t subpass_idx)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < loc->postSubpassSampleLocationsCount; i++) {
|
||||||
|
if (loc->pPostSubpassSampleLocations[i].subpassIndex == subpass_idx)
|
||||||
|
return &loc->pPostSubpassSampleLocations[i].sampleLocationsInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
vk_image_layout_supports_input_attachment(VkImageLayout layout)
|
vk_image_layout_supports_input_attachment(VkImageLayout layout)
|
||||||
{
|
{
|
||||||
|
@ -1072,6 +1169,7 @@ transition_image_range(const struct vk_image_view *image_view,
|
||||||
VkImageLayout new_layout,
|
VkImageLayout new_layout,
|
||||||
VkImageLayout old_stencil_layout,
|
VkImageLayout old_stencil_layout,
|
||||||
VkImageLayout new_stencil_layout,
|
VkImageLayout new_stencil_layout,
|
||||||
|
const VkSampleLocationsInfoEXT *sample_locations,
|
||||||
uint32_t *barrier_count,
|
uint32_t *barrier_count,
|
||||||
uint32_t max_barrier_count,
|
uint32_t max_barrier_count,
|
||||||
VkImageMemoryBarrier2 *barriers)
|
VkImageMemoryBarrier2 *barriers)
|
||||||
|
@ -1111,6 +1209,7 @@ transition_image_range(const struct vk_image_view *image_view,
|
||||||
assert(*barrier_count < max_barrier_count);
|
assert(*barrier_count < max_barrier_count);
|
||||||
barriers[(*barrier_count)++] = (VkImageMemoryBarrier2) {
|
barriers[(*barrier_count)++] = (VkImageMemoryBarrier2) {
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||||
|
.pNext = sample_locations,
|
||||||
.srcStageMask = src_sa.stages,
|
.srcStageMask = src_sa.stages,
|
||||||
.srcAccessMask = src_sa.access,
|
.srcAccessMask = src_sa.access,
|
||||||
.dstStageMask = dst_sa.stages,
|
.dstStageMask = dst_sa.stages,
|
||||||
|
@ -1320,6 +1419,7 @@ transition_attachment(struct vk_command_buffer *cmd_buffer,
|
||||||
transition_image_range(image_view, range,
|
transition_image_range(image_view, range,
|
||||||
att_view_state->layout, layout,
|
att_view_state->layout, layout,
|
||||||
att_view_state->stencil_layout, stencil_layout,
|
att_view_state->stencil_layout, stencil_layout,
|
||||||
|
att_view_state->sample_locations,
|
||||||
barrier_count, max_barrier_count, barriers);
|
barrier_count, max_barrier_count, barriers);
|
||||||
|
|
||||||
att_view_state->layout = layout;
|
att_view_state->layout = layout;
|
||||||
|
@ -1531,6 +1631,7 @@ begin_subpass(struct vk_command_buffer *cmd_buffer,
|
||||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA,
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const VkSampleLocationsInfoEXT *sample_locations = NULL;
|
||||||
if (subpass->depth_stencil_attachment != NULL) {
|
if (subpass->depth_stencil_attachment != NULL) {
|
||||||
const struct vk_subpass_attachment *sp_att =
|
const struct vk_subpass_attachment *sp_att =
|
||||||
subpass->depth_stencil_attachment;
|
subpass->depth_stencil_attachment;
|
||||||
|
@ -1612,6 +1713,37 @@ begin_subpass(struct vk_command_buffer *cmd_buffer,
|
||||||
stencil_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
stencil_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* From the Vulkan 1.3.212 spec:
|
||||||
|
*
|
||||||
|
* "If the current render pass does not use the attachment as a
|
||||||
|
* depth/stencil attachment in any subpass that happens-before, the
|
||||||
|
* automatic layout transition uses the sample locations state
|
||||||
|
* specified in the sampleLocationsInfo member of the element of the
|
||||||
|
* VkRenderPassSampleLocationsBeginInfoEXT::pAttachmentInitialSampleLocations
|
||||||
|
* array for which the attachmentIndex member equals the attachment
|
||||||
|
* index of the attachment, if one is specified. Otherwise, the
|
||||||
|
* automatic layout transition uses the sample locations state
|
||||||
|
* specified in the sampleLocationsInfo member of the element of the
|
||||||
|
* VkRenderPassSampleLocationsBeginInfoEXT::pPostSubpassSampleLocations
|
||||||
|
* array for which the subpassIndex member equals the index of the
|
||||||
|
* subpass that last used the attachment as a depth/stencil
|
||||||
|
* attachment, if one is specified."
|
||||||
|
*
|
||||||
|
* Unfortunately, this says nothing whatsoever about multiview.
|
||||||
|
* However, since multiview render passes are described as a single-view
|
||||||
|
* render pass repeated per-view, we assume this is per-view.
|
||||||
|
*/
|
||||||
|
if (cmd_buffer->pass_sample_locations != NULL &&
|
||||||
|
(att_state->image_view->image->create_flags &
|
||||||
|
VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT)) {
|
||||||
|
sample_locations =
|
||||||
|
get_subpass_sample_locations(cmd_buffer->pass_sample_locations,
|
||||||
|
subpass_idx);
|
||||||
|
|
||||||
|
u_foreach_bit(view, subpass->view_mask)
|
||||||
|
att_state->views[view].sample_locations = sample_locations;
|
||||||
|
}
|
||||||
|
|
||||||
if (sp_att->resolve != NULL) {
|
if (sp_att->resolve != NULL) {
|
||||||
const struct vk_subpass_attachment *res_sp_att = sp_att->resolve;
|
const struct vk_subpass_attachment *res_sp_att = sp_att->resolve;
|
||||||
assert(res_sp_att->attachment < pass->attachment_count);
|
assert(res_sp_att->attachment < pass->attachment_count);
|
||||||
|
@ -1836,6 +1968,12 @@ begin_subpass(struct vk_command_buffer *cmd_buffer,
|
||||||
__vk_append_struct(&rendering, &fsr_attachment);
|
__vk_append_struct(&rendering, &fsr_attachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkSampleLocationsInfoEXT sample_locations_tmp;
|
||||||
|
if (sample_locations) {
|
||||||
|
sample_locations_tmp = *sample_locations;
|
||||||
|
__vk_append_struct(&rendering, &sample_locations_tmp);
|
||||||
|
}
|
||||||
|
|
||||||
disp->CmdBeginRendering(vk_command_buffer_to_handle(cmd_buffer),
|
disp->CmdBeginRendering(vk_command_buffer_to_handle(cmd_buffer),
|
||||||
&rendering);
|
&rendering);
|
||||||
|
|
||||||
|
@ -1977,6 +2115,33 @@ vk_common_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
|
||||||
att_state->clear_value = pRenderPassBeginInfo->pClearValues[a];
|
att_state->clear_value = pRenderPassBeginInfo->pClearValues[a];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const VkRenderPassSampleLocationsBeginInfoEXT *rp_sl_info =
|
||||||
|
vk_find_struct_const(pRenderPassBeginInfo->pNext,
|
||||||
|
RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT);
|
||||||
|
if (rp_sl_info) {
|
||||||
|
cmd_buffer->pass_sample_locations = clone_rp_sample_locations(rp_sl_info);
|
||||||
|
assert(cmd_buffer->pass_sample_locations);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < rp_sl_info->attachmentInitialSampleLocationsCount; i++) {
|
||||||
|
const VkAttachmentSampleLocationsEXT *att_sl =
|
||||||
|
&rp_sl_info->pAttachmentInitialSampleLocations[i];
|
||||||
|
|
||||||
|
assert(att_sl->attachmentIndex < pass->attachment_count);
|
||||||
|
struct vk_attachment_state *att_state =
|
||||||
|
&cmd_buffer->attachments[att_sl->attachmentIndex];
|
||||||
|
|
||||||
|
/* Sample locations only matter for depth/stencil images created with
|
||||||
|
* VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
|
||||||
|
*/
|
||||||
|
if (vk_format_is_depth_or_stencil(att_state->image_view->format) &&
|
||||||
|
(att_state->image_view->image->create_flags &
|
||||||
|
VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT)) {
|
||||||
|
for (uint32_t v = 0; v < MESA_VK_MAX_MULTIVIEW_VIEW_COUNT; v++)
|
||||||
|
att_state->views[v].sample_locations = &att_sl->sampleLocationsInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
begin_subpass(cmd_buffer, pSubpassBeginInfo);
|
begin_subpass(cmd_buffer, pSubpassBeginInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1989,6 +2154,9 @@ vk_command_buffer_reset_render_pass(struct vk_command_buffer *cmd_buffer)
|
||||||
if (cmd_buffer->attachments != cmd_buffer->_attachments)
|
if (cmd_buffer->attachments != cmd_buffer->_attachments)
|
||||||
free(cmd_buffer->attachments);
|
free(cmd_buffer->attachments);
|
||||||
cmd_buffer->attachments = NULL;
|
cmd_buffer->attachments = NULL;
|
||||||
|
if (cmd_buffer->pass_sample_locations != NULL)
|
||||||
|
vk_free(vk_default_allocator(), cmd_buffer->pass_sample_locations);
|
||||||
|
cmd_buffer->pass_sample_locations = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
VKAPI_ATTR void VKAPI_CALL
|
VKAPI_ATTR void VKAPI_CALL
|
||||||
|
|
Loading…
Reference in New Issue