ac: use 1D GEPs for descriptors and constants
[mesa.git] / src / amd / vulkan / radv_meta_clear.c
index 7a364ec684a733b0319e53c17ebaaa24371dc45e..40ecfe001d1e081ecb8afebe16e9c6ad28887eb4 100644 (file)
@@ -232,8 +232,8 @@ create_color_renderpass(struct radv_device *device,
                                                               .attachment = VK_ATTACHMENT_UNUSED,
                                                               .layout = VK_IMAGE_LAYOUT_GENERAL,
                                                       },
-                                                      .preserveAttachmentCount = 1,
-                                                      .pPreserveAttachments = (uint32_t[]) { 0 },
+                                                      .preserveAttachmentCount = 0,
+                                                      .pPreserveAttachments = NULL,
                                               },
                                                                .dependencyCount = 0,
                                                                         }, &device->meta_state.alloc, pass);
@@ -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;
@@ -423,10 +438,10 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer,
                .color_attachments = (struct radv_subpass_attachment[]) {
                        subpass->color_attachments[clear_att->colorAttachment]
                },
-               .depth_stencil_attachment = (struct radv_subpass_attachment) { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_UNDEFINED }
+               .depth_stencil_attachment = NULL,
        };
 
-       radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass, false);
+       radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass);
 
        radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
                             pipeline);
@@ -450,7 +465,7 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer,
                radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, clear_rect->baseArrayLayer);
        }
 
-       radv_cmd_buffer_set_subpass(cmd_buffer, subpass, false);
+       radv_cmd_buffer_set_subpass(cmd_buffer, subpass);
 }
 
 
@@ -532,8 +547,8 @@ create_depthstencil_renderpass(struct radv_device *device,
                                                               .attachment = 0,
                                                               .layout = VK_IMAGE_LAYOUT_GENERAL,
                                                       },
-                                                      .preserveAttachmentCount = 1,
-                                                      .pPreserveAttachments = (uint32_t[]) { 0 },
+                                                      .preserveAttachmentCount = 0,
+                                                      .pPreserveAttachments = NULL,
                                               },
                                                                .dependencyCount = 0,
                                                                         }, &device->meta_state.alloc, render_pass);
@@ -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;
 }
@@ -702,14 +720,25 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
        struct radv_meta_state *meta_state = &device->meta_state;
        const struct radv_subpass *subpass = cmd_buffer->state.subpass;
        const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
-       const uint32_t pass_att = subpass->depth_stencil_attachment.attachment;
+       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))
@@ -731,7 +760,7 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
                                                         iview,
                                                         samples_log2,
                                                         aspects,
-                                                        subpass->depth_stencil_attachment.layout,
+                                                        subpass->depth_stencil_attachment->layout,
                                                         clear_rect,
                                                         clear_value);
        if (!pipeline)
@@ -741,7 +770,7 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
                             pipeline);
 
        if (depth_view_can_fast_clear(cmd_buffer, iview, aspects,
-                                     subpass->depth_stencil_attachment.layout,
+                                     subpass->depth_stencil_attachment->layout,
                                      clear_rect, clear_value))
                radv_update_ds_clear_metadata(cmd_buffer, iview->image,
                                              clear_value, aspects);
@@ -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 {
@@ -899,14 +928,6 @@ radv_image_can_fast_clear(struct radv_device *device,  struct radv_image *image)
        } else {
                if (!radv_image_has_htile(image))
                        return false;
-
-               /* GFX8 only supports 32-bit depth surfaces but we can enable
-                * TC-compat HTILE for 16-bit surfaces if no Z planes are
-                * compressed. Though, fast HTILE clears don't seem to work.
-                */
-               if (device->physical_device->rad_info.chip_class == VI &&
-                   image->vk_format == VK_FORMAT_D16_UNORM)
-                       return false;
        }
 
        /* Do not fast clears 3D images. */
@@ -923,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))
@@ -1009,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);
        }
 
@@ -1036,8 +1061,8 @@ build_clear_htile_mask_shader()
        b.shader->info.cs.local_size[1] = 1;
        b.shader->info.cs.local_size[2] = 1;
 
-       nir_ssa_def *invoc_id = nir_load_system_value(&b, nir_intrinsic_load_local_invocation_id, 0);
-       nir_ssa_def *wg_id = nir_load_system_value(&b, nir_intrinsic_load_work_group_id, 0);
+       nir_ssa_def *invoc_id = nir_load_local_invocation_id(&b);
+       nir_ssa_def *wg_id = nir_load_work_group_id(&b);
        nir_ssa_def *block_size = nir_imm_ivec4(&b,
                                                b.shader->info.cs.local_size[0],
                                                b.shader->info.cs.local_size[1],
@@ -1053,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 =
@@ -1088,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);
 
@@ -1295,6 +1322,16 @@ radv_clear_cmask(struct radv_cmd_buffer *cmd_buffer,
                                image->cmask.size, value);
 }
 
+
+uint32_t
+radv_clear_fmask(struct radv_cmd_buffer *cmd_buffer,
+                struct radv_image *image, uint32_t value)
+{
+       return radv_fill_buffer(cmd_buffer, image->bo,
+                               image->offset + image->fmask.offset,
+                               image->fmask.size, value);
+}
+
 uint32_t
 radv_clear_dcc(struct radv_cmd_buffer *cmd_buffer,
               struct radv_image *image, uint32_t value)
@@ -1304,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,
@@ -1520,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,
@@ -1534,9 +1575,12 @@ emit_clear(struct radv_cmd_buffer *cmd_buffer,
                        emit_color_clear(cmd_buffer, clear_att, clear_rect, view_mask);
                }
        } else {
-               const uint32_t pass_att = subpass->depth_stencil_attachment.attachment;
-               VkImageLayout image_layout = subpass->depth_stencil_attachment.layout;
-               const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
+               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 ? fb->attachments[pass_att].attachment : NULL;
                VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
 
                assert(aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
@@ -1578,7 +1622,10 @@ radv_subpass_needs_clear(struct radv_cmd_buffer *cmd_buffer)
                        return true;
        }
 
-       a = cmd_state->subpass->depth_stencil_attachment.attachment;
+       if (!cmd_state->subpass->depth_stencil_attachment)
+               return false;
+
+       a = cmd_state->subpass->depth_stencil_attachment->attachment;
        return radv_attachment_needs_clear(cmd_state, a);
 }
 
@@ -1647,17 +1694,19 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer)
                                              &post_flush);
        }
 
-       uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment;
-       if (radv_attachment_needs_clear(cmd_state, ds)) {
-               VkClearAttachment clear_att = {
-                       .aspectMask = cmd_state->attachments[ds].pending_clear_aspects,
-                       .clearValue = cmd_state->attachments[ds].clear_value,
-               };
-
-               radv_subpass_clear_attachment(cmd_buffer,
-                                             &cmd_state->attachments[ds],
-                                             &clear_att, &pre_flush,
-                                             &post_flush);
+       if (cmd_state->subpass->depth_stencil_attachment) {
+               uint32_t ds = cmd_state->subpass->depth_stencil_attachment->attachment;
+               if (radv_attachment_needs_clear(cmd_state, ds)) {
+                       VkClearAttachment clear_att = {
+                               .aspectMask = cmd_state->attachments[ds].pending_clear_aspects,
+                               .clearValue = cmd_state->attachments[ds].clear_value,
+                       };
+
+                       radv_subpass_clear_attachment(cmd_buffer,
+                                                     &cmd_state->attachments[ds],
+                                                     &clear_att, &pre_flush,
+                                                     &post_flush);
+               }
        }
 
        radv_meta_restore(&saved_state, cmd_buffer);