radv: implement VK_KHR_separate_depth_stencil_layouts
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Mon, 9 Dec 2019 12:56:24 +0000 (13:56 +0100)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Tue, 10 Dec 2019 12:16:17 +0000 (13:16 +0100)
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
docs/relnotes/new_features.txt
src/amd/vulkan/radv_cmd_buffer.c
src/amd/vulkan/radv_device.c
src/amd/vulkan/radv_extensions.py
src/amd/vulkan/radv_image.c
src/amd/vulkan/radv_pass.c
src/amd/vulkan/radv_private.h

index a784d65f6b62a6945b25372f0acb79e8f4076ba5..f8449b11b1764bbb39778c9bb37fbfdbde847153 100644 (file)
@@ -1,5 +1,5 @@
 VK_AMD_device_coherent_memory on RADV.
 VK_EXT_subgroup_size_control on RADV.
-VK_KHR_separate_depth_stencil_layouts on Intel.
+VK_KHR_separate_depth_stencil_layouts on Intel, RADV.
 VK_KHR_shader_subgroup_extended_types on RADV.
 EXT_direct_state_access for compatibility profile.
index bbbb190394cf96e9d17616e3cf644b740467f59b..0c62eacf05cb8deb884125a07f8b08587a3dd1eb 100644 (file)
@@ -2974,14 +2974,48 @@ static void radv_handle_subpass_image_transition(struct radv_cmd_buffer *cmd_buf
        sample_locs = radv_get_attachment_sample_locations(cmd_buffer, idx,
                                                           begin_subpass);
 
-       radv_handle_image_transition(cmd_buffer,
-                                    view->image,
-                                    cmd_buffer->state.attachments[idx].current_layout,
-                                    cmd_buffer->state.attachments[idx].current_in_render_loop,
-                                    att.layout, att.in_render_loop,
-                                    0, 0, &range, sample_locs);
+       /* Determine if the subpass uses separate depth/stencil layouts. */
+       bool uses_separate_depth_stencil_layouts = false;
+       if ((cmd_buffer->state.attachments[idx].current_layout !=
+            cmd_buffer->state.attachments[idx].current_stencil_layout) ||
+           (att.layout != att.stencil_layout)) {
+               uses_separate_depth_stencil_layouts = true;
+       }
+
+       /* For separate layouts, perform depth and stencil transitions
+        * separately.
+        */
+       if (uses_separate_depth_stencil_layouts &&
+           (range.aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT |
+                                 VK_IMAGE_ASPECT_STENCIL_BIT))) {
+               /* Depth-only transitions. */
+               range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
+               radv_handle_image_transition(cmd_buffer,
+                                            view->image,
+                                            cmd_buffer->state.attachments[idx].current_layout,
+                                            cmd_buffer->state.attachments[idx].current_in_render_loop,
+                                            att.layout, att.in_render_loop,
+                                            0, 0, &range, sample_locs);
+
+               /* Stencil-only transitions. */
+               range.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
+               radv_handle_image_transition(cmd_buffer,
+                                            view->image,
+                                            cmd_buffer->state.attachments[idx].current_stencil_layout,
+                                            cmd_buffer->state.attachments[idx].current_in_render_loop,
+                                            att.stencil_layout, att.in_render_loop,
+                                            0, 0, &range, sample_locs);
+       } else {
+               radv_handle_image_transition(cmd_buffer,
+                                            view->image,
+                                            cmd_buffer->state.attachments[idx].current_layout,
+                                            cmd_buffer->state.attachments[idx].current_in_render_loop,
+                                            att.layout, att.in_render_loop,
+                                            0, 0, &range, sample_locs);
+       }
 
        cmd_buffer->state.attachments[idx].current_layout = att.layout;
+       cmd_buffer->state.attachments[idx].current_stencil_layout = att.stencil_layout;
        cmd_buffer->state.attachments[idx].current_in_render_loop = att.in_render_loop;
 
 
@@ -3138,6 +3172,7 @@ radv_cmd_state_setup_attachments(struct radv_cmd_buffer *cmd_buffer,
                }
 
                state->attachments[i].current_layout = att->initial_layout;
+               state->attachments[i].current_stencil_layout = att->stencil_initial_layout;
                state->attachments[i].sample_location.count = 0;
 
                struct radv_image_view *iview;
@@ -4218,7 +4253,8 @@ radv_cmd_buffer_end_subpass(struct radv_cmd_buffer *cmd_buffer)
                        continue;
 
                VkImageLayout layout = state->pass->attachments[a].final_layout;
-               struct radv_subpass_attachment att = { a, layout };
+               VkImageLayout stencil_layout = state->pass->attachments[a].stencil_final_layout;
+               struct radv_subpass_attachment att = { a, layout, stencil_layout };
                radv_handle_subpass_image_transition(cmd_buffer, att, false);
        }
 }
index fe8430e7ac5fe36acbda64f004e389a3565a1d89..2a65fb9cc3a7dd9eb396b6bff21fee888676cbe6 100644 (file)
@@ -1192,6 +1192,12 @@ void radv_GetPhysicalDeviceFeatures2(
                        features->shaderSubgroupExtendedTypes = true;
                        break;
                }
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR: {
+                       VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *features =
+                               (VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *)ext;
+                       features->separateDepthStencilLayouts = true;
+                       break;
+               }
                default:
                        break;
                }
index f49f34fb9ed5410955378883441b5cb94e3c2266..2a1d50f12543d274ad64e2b9f3df08b57da0f35f 100644 (file)
@@ -87,6 +87,7 @@ EXTENSIONS = [
     Extension('VK_KHR_relaxed_block_layout',              1, True),
     Extension('VK_KHR_sampler_mirror_clamp_to_edge',      1, True),
     Extension('VK_KHR_sampler_ycbcr_conversion',          1, True),
+    Extension('VK_KHR_separate_depth_stencil_layouts',    1, True),
     Extension('VK_KHR_shader_atomic_int64',               1, 'LLVM_VERSION_MAJOR >= 9'),
     Extension('VK_KHR_shader_clock',                      1, True),
     Extension('VK_KHR_shader_draw_parameters',            1, True),
index fcdab593937701efd10fd5bf3bebfc92bfe8122d..520d078e4a97a560612e937cce7f8f2e5f9329ba 100644 (file)
@@ -1757,6 +1757,8 @@ bool radv_layout_has_htile(const struct radv_image *image,
 
        return radv_image_has_htile(image) &&
               (layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
+               layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
+               layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR ||
                (layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
                 queue_mask == (1u << RADV_QUEUE_GENERAL)));
 }
@@ -1771,6 +1773,8 @@ bool radv_layout_is_htile_compressed(const struct radv_image *image,
 
        return radv_image_has_htile(image) &&
               (layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
+               layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
+               layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR ||
                (layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
                 queue_mask == (1u << RADV_QUEUE_GENERAL)));
 }
index 2b60a25535a4c28ecbfdc0513d6a38df8f16e8b3..c47720213a8cf567eb2db3a640fd432e1d3830dd 100644 (file)
@@ -226,6 +226,8 @@ VkResult radv_CreateRenderPass(
                att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
                att->initial_layout =  pCreateInfo->pAttachments[i].initialLayout;
                att->final_layout =  pCreateInfo->pAttachments[i].finalLayout;
+               att->stencil_initial_layout = pCreateInfo->pAttachments[i].initialLayout;
+               att->stencil_final_layout = pCreateInfo->pAttachments[i].finalLayout;
                // att->store_op = pCreateInfo->pAttachments[i].storeOp;
                // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
        }
@@ -269,6 +271,7 @@ VkResult radv_CreateRenderPass(
                                subpass->input_attachments[j] = (struct radv_subpass_attachment) {
                                        .attachment = desc->pInputAttachments[j].attachment,
                                        .layout = desc->pInputAttachments[j].layout,
+                                       .stencil_layout = desc->pInputAttachments[j].layout,
                                };
                        }
                }
@@ -293,6 +296,7 @@ VkResult radv_CreateRenderPass(
                                subpass->resolve_attachments[j] = (struct radv_subpass_attachment) {
                                        .attachment = desc->pResolveAttachments[j].attachment,
                                        .layout = desc->pResolveAttachments[j].layout,
+                                       .stencil_layout = desc->pResolveAttachments[j].layout,
                                };
                        }
                }
@@ -303,6 +307,7 @@ VkResult radv_CreateRenderPass(
                        *subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
                                .attachment = desc->pDepthStencilAttachment->attachment,
                                .layout = desc->pDepthStencilAttachment->layout,
+                               .stencil_layout = desc->pDepthStencilAttachment->layout,
                        };
                }
        }
@@ -372,6 +377,9 @@ VkResult radv_CreateRenderPass2KHR(
 
        for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
                struct radv_render_pass_attachment *att = &pass->attachments[i];
+               const VkAttachmentDescriptionStencilLayoutKHR *stencil_layout =
+                       vk_find_struct_const(pCreateInfo->pAttachments[i].pNext,
+                                            ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR);
 
                att->format = pCreateInfo->pAttachments[i].format;
                att->samples = pCreateInfo->pAttachments[i].samples;
@@ -379,6 +387,12 @@ VkResult radv_CreateRenderPass2KHR(
                att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
                att->initial_layout =  pCreateInfo->pAttachments[i].initialLayout;
                att->final_layout =  pCreateInfo->pAttachments[i].finalLayout;
+               att->stencil_initial_layout = (stencil_layout ?
+                                              stencil_layout->stencilInitialLayout :
+                                              pCreateInfo->pAttachments[i].initialLayout);
+               att->stencil_final_layout = (stencil_layout ?
+                                            stencil_layout->stencilFinalLayout :
+                                            pCreateInfo->pAttachments[i].finalLayout);
                // att->store_op = pCreateInfo->pAttachments[i].storeOp;
                // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
        }
@@ -417,9 +431,16 @@ VkResult radv_CreateRenderPass2KHR(
                        p += desc->inputAttachmentCount;
 
                        for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
+                               const VkAttachmentReferenceStencilLayoutKHR *stencil_attachment =
+                                   vk_find_struct_const(desc->pInputAttachments[j].pNext,
+                                                        ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR);
+
                                subpass->input_attachments[j] = (struct radv_subpass_attachment) {
                                        .attachment = desc->pInputAttachments[j].attachment,
                                        .layout = desc->pInputAttachments[j].layout,
+                                       .stencil_layout = (stencil_attachment ?
+                                                          stencil_attachment->stencilLayout :
+                                                          desc->pInputAttachments[j].layout),
                                };
                        }
                }
@@ -451,9 +472,16 @@ VkResult radv_CreateRenderPass2KHR(
                if (desc->pDepthStencilAttachment) {
                        subpass->depth_stencil_attachment = p++;
 
+                       const VkAttachmentReferenceStencilLayoutKHR *stencil_attachment =
+                           vk_find_struct_const(desc->pDepthStencilAttachment->pNext,
+                                                ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR);
+
                        *subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
                                .attachment = desc->pDepthStencilAttachment->attachment,
                                .layout = desc->pDepthStencilAttachment->layout,
+                               .stencil_layout = (stencil_attachment ?
+                                                  stencil_attachment->stencilLayout :
+                                                  desc->pDepthStencilAttachment->layout),
                        };
                }
 
@@ -464,9 +492,16 @@ VkResult radv_CreateRenderPass2KHR(
                if (ds_resolve && ds_resolve->pDepthStencilResolveAttachment) {
                        subpass->ds_resolve_attachment = p++;
 
+                       const VkAttachmentReferenceStencilLayoutKHR *stencil_resolve_attachment =
+                           vk_find_struct_const(ds_resolve->pDepthStencilResolveAttachment->pNext,
+                                                ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR);
+
                        *subpass->ds_resolve_attachment = (struct radv_subpass_attachment) {
                                .attachment =  ds_resolve->pDepthStencilResolveAttachment->attachment,
                                .layout =      ds_resolve->pDepthStencilResolveAttachment->layout,
+                               .stencil_layout = (stencil_resolve_attachment ?
+                                                  stencil_resolve_attachment->stencilLayout :
+                                                  ds_resolve->pDepthStencilResolveAttachment->layout),
                        };
 
                        subpass->depth_resolve_mode = ds_resolve->depthResolveMode;
index 1e15de10924ebf84a3edd5afb4c48d9c21bdadfb..1be61679d8ae6e2d16447dfc0775d254392bfb44 100644 (file)
@@ -1195,6 +1195,7 @@ struct radv_attachment_state {
        uint32_t                                     cleared_views;
        VkClearValue                                 clear_value;
        VkImageLayout                                current_layout;
+       VkImageLayout                                current_stencil_layout;
        bool                                         current_in_render_loop;
        struct radv_sample_locations_state           sample_location;
 
@@ -2128,6 +2129,7 @@ void radv_subpass_barrier(struct radv_cmd_buffer *cmd_buffer,
 struct radv_subpass_attachment {
        uint32_t         attachment;
        VkImageLayout    layout;
+       VkImageLayout    stencil_layout;
        bool             in_render_loop;
 };
 
@@ -2167,6 +2169,8 @@ struct radv_render_pass_attachment {
        VkAttachmentLoadOp                           stencil_load_op;
        VkImageLayout                                initial_layout;
        VkImageLayout                                final_layout;
+       VkImageLayout                                stencil_initial_layout;
+       VkImageLayout                                stencil_final_layout;
 
        /* The subpass id in which the attachment will be used first/last. */
        uint32_t                                     first_subpass_idx;