ac: use 1D GEPs for descriptors and constants
[mesa.git] / src / amd / vulkan / radv_meta_clear.c
index 819ec060fc6aab2d879f8647bc806c21554097fb..40ecfe001d1e081ecb8afebe16e9c6ad28887eb4 100644 (file)
@@ -370,14 +370,29 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer,
        const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
        const uint32_t subpass_att = clear_att->colorAttachment;
        const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment;
-       const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
-       const uint32_t samples = iview->image->info.samples;
-       const uint32_t samples_log2 = ffs(samples) - 1;
-       unsigned fs_key = radv_format_meta_fs_key(iview->vk_format);
+       const struct radv_image_view *iview = fb ? fb->attachments[pass_att].attachment : NULL;
+       uint32_t samples, samples_log2;
+       VkFormat format;
+       unsigned fs_key;
        VkClearColorValue clear_value = clear_att->clearValue.color;
        VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
        VkPipeline pipeline;
 
+       /* When a framebuffer is bound to the current command buffer, get the
+        * number of samples from it. Otherwise, get the number of samples from
+        * the render pass because it's likely a secondary command buffer.
+        */
+       if (iview) {
+               samples = iview->image->info.samples;
+               format = iview->vk_format;
+       } else {
+               samples = cmd_buffer->state.pass->attachments[pass_att].samples;
+               format = cmd_buffer->state.pass->attachments[pass_att].format;
+       }
+
+       samples_log2 = ffs(samples) - 1;
+       fs_key = radv_format_meta_fs_key(format);
+
        if (fs_key == -1) {
                radv_finishme("color clears incomplete");
                return;
@@ -617,6 +632,9 @@ static bool depth_view_can_fast_clear(struct radv_cmd_buffer *cmd_buffer,
                                      const VkClearRect *clear_rect,
                                      VkClearDepthStencilValue clear_value)
 {
+       if (!iview)
+               return false;
+
        uint32_t queue_mask = radv_image_queue_family_mask(iview->image,
                                                           cmd_buffer->queue_family_index,
                                                           cmd_buffer->queue_family_index);
@@ -633,7 +651,7 @@ static bool depth_view_can_fast_clear(struct radv_cmd_buffer *cmd_buffer,
            iview->base_mip == 0 &&
            iview->base_layer == 0 &&
            radv_layout_is_htile_compressed(iview->image, layout, queue_mask) &&
-           !radv_image_extent_compare(iview->image, &iview->extent))
+           radv_image_extent_compare(iview->image, &iview->extent))
                return true;
        return false;
 }
@@ -705,11 +723,22 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
        const uint32_t pass_att = subpass->depth_stencil_attachment->attachment;
        VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
        VkImageAspectFlags aspects = clear_att->aspectMask;
-       const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
-       const uint32_t samples = iview->image->info.samples;
-       const uint32_t samples_log2 = ffs(samples) - 1;
+       const struct radv_image_view *iview = fb ? fb->attachments[pass_att].attachment : NULL;
+       uint32_t samples, samples_log2;
        VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
 
+       /* When a framebuffer is bound to the current command buffer, get the
+        * number of samples from it. Otherwise, get the number of samples from
+        * the render pass because it's likely a secondary command buffer.
+        */
+       if (iview) {
+               samples = iview->image->info.samples;
+       } else {
+               samples = cmd_buffer->state.pass->attachments[pass_att].samples;
+       }
+
+       samples_log2 = ffs(samples) - 1;
+
        assert(pass_att != VK_ATTACHMENT_UNUSED);
 
        if (!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT))
@@ -840,7 +869,7 @@ radv_get_htile_fast_clear_value(const struct radv_image *image,
 {
        uint32_t clear_value;
 
-       if (!image->surface.has_stencil) {
+       if (!image->planes[0].surface.has_stencil) {
                clear_value = value.depth ? 0xfffffff0 : 0;
        } else {
                clear_value = value.depth ? 0xfffc0000 : 0;
@@ -854,7 +883,7 @@ radv_get_htile_mask(const struct radv_image *image, VkImageAspectFlags aspects)
 {
        uint32_t mask = 0;
 
-       if (!image->surface.has_stencil) {
+       if (!image->planes[0].surface.has_stencil) {
                /* All the HTILE buffer is used when there is no stencil. */
                mask = UINT32_MAX;
        } else {
@@ -915,7 +944,11 @@ static bool
 radv_image_view_can_fast_clear(struct radv_device *device,
                               const struct radv_image_view *iview)
 {
-       struct radv_image *image = iview->image;
+       struct radv_image *image;
+
+       if (!iview)
+               return false;
+       image = iview->image;
 
        /* Only fast clear if the image itself can be fast cleared. */
        if (!radv_image_can_fast_clear(device, image))
@@ -1001,13 +1034,13 @@ radv_fast_clear_depth(struct radv_cmd_buffer *cmd_buffer,
                /* Clear the whole HTILE buffer. */
                flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo,
                                              iview->image->offset + iview->image->htile_offset,
-                                             iview->image->surface.htile_size, clear_word);
+                                             iview->image->planes[0].surface.htile_size, clear_word);
        } else {
                /* Only clear depth or stencil bytes in the HTILE buffer. */
                assert(cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9);
                flush_bits = clear_htile_mask(cmd_buffer, iview->image->bo,
                                              iview->image->offset + iview->image->htile_offset,
-                                             iview->image->surface.htile_size, clear_word,
+                                             iview->image->planes[0].surface.htile_size, clear_word,
                                              htile_mask);
        }
 
@@ -1045,9 +1078,10 @@ build_clear_htile_mask_shader()
                                           nir_intrinsic_vulkan_resource_index);
 
        buf->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0));
+       buf->num_components = 1;
        nir_intrinsic_set_desc_set(buf, 0);
        nir_intrinsic_set_binding(buf, 0);
-       nir_ssa_dest_init(&buf->instr, &buf->dest, 1, 32, NULL);
+       nir_ssa_dest_init(&buf->instr, &buf->dest, buf->num_components, 32, NULL);
        nir_builder_instr_insert(&b, &buf->instr);
 
        nir_intrinsic_instr *constants =
@@ -1080,6 +1114,7 @@ build_clear_htile_mask_shader()
        store->src[1] = nir_src_for_ssa(&buf->dest.ssa);
        store->src[2] = nir_src_for_ssa(offset);
        nir_intrinsic_set_write_mask(store, 0xf);
+       nir_intrinsic_set_access(store, ACCESS_NON_READABLE);
        store->num_components = 4;
        nir_builder_instr_insert(&b, &store->instr);
 
@@ -1306,7 +1341,7 @@ radv_clear_dcc(struct radv_cmd_buffer *cmd_buffer,
 
        return radv_fill_buffer(cmd_buffer, image->bo,
                                image->offset + image->dcc_offset,
-                               image->surface.dcc_size, value);
+                               image->planes[0].surface.dcc_size, value);
 }
 
 static void vi_get_fast_clear_parameters(VkFormat format,
@@ -1522,9 +1557,13 @@ emit_clear(struct radv_cmd_buffer *cmd_buffer,
 
        if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
                const uint32_t subpass_att = clear_att->colorAttachment;
+               assert(subpass_att < subpass->color_count);
                const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment;
+               if (pass_att == VK_ATTACHMENT_UNUSED)
+                       return;
+
                VkImageLayout image_layout = subpass->color_attachments[subpass_att].layout;
-               const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
+               const struct radv_image_view *iview = fb ? fb->attachments[pass_att].attachment : NULL;
                VkClearColorValue clear_value = clear_att->clearValue.color;
 
                if (radv_can_fast_clear_color(cmd_buffer, iview, image_layout,
@@ -1537,8 +1576,11 @@ emit_clear(struct radv_cmd_buffer *cmd_buffer,
                }
        } else {
                const uint32_t pass_att = subpass->depth_stencil_attachment->attachment;
+               if (pass_att == VK_ATTACHMENT_UNUSED)
+                       return;
+
                VkImageLayout image_layout = subpass->depth_stencil_attachment->layout;
-               const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
+               const struct radv_image_view *iview = fb ? fb->attachments[pass_att].attachment : NULL;
                VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
 
                assert(aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |