radv/amdgpu: Add some debug flags.
[mesa.git] / src / amd / vulkan / radv_meta_clear.c
index 601c3de4ebaaa9104c510417a5e8c5ec8ea8ba5b..c4f728b5b078ec374a0cc14eb2c840c3323624dd 100644 (file)
@@ -98,6 +98,16 @@ build_color_shaders(struct nir_shader **out_vs,
        nir_copy_var(&vs_b, vs_out_color, vs_in_color);
        nir_copy_var(&fs_b, fs_out_color, fs_in_color);
 
+       const struct glsl_type *layer_type = glsl_int_type();
+       nir_variable *vs_out_layer =
+               nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type,
+                                   "v_layer");
+       vs_out_layer->data.location = VARYING_SLOT_LAYER;
+       vs_out_layer->data.interpolation = INTERP_MODE_FLAT;
+       nir_ssa_def *inst_id = nir_load_system_value(&vs_b, nir_intrinsic_load_instance_id, 0);
+
+       nir_store_var(&vs_b, vs_out_layer, inst_id, 0x1);
+
        *out_vs = vs_b.shader;
        *out_fs = fs_b.shader;
 }
@@ -204,13 +214,51 @@ create_pipeline(struct radv_device *device,
        return result;
 }
 
+static VkResult
+create_color_renderpass(struct radv_device *device,
+                       VkFormat vk_format,
+                       uint32_t samples,
+                       VkRenderPass *pass)
+{
+       return radv_CreateRenderPass(radv_device_to_handle(device),
+                                      &(VkRenderPassCreateInfo) {
+                                              .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+                                                      .attachmentCount = 1,
+                                                      .pAttachments = &(VkAttachmentDescription) {
+                                                      .format = vk_format,
+                                                      .samples = samples,
+                                                      .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
+                                                      .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+                                                      .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
+                                                      .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
+                                              },
+                                                      .subpassCount = 1,
+                                                               .pSubpasses = &(VkSubpassDescription) {
+                                                      .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
+                                                      .inputAttachmentCount = 0,
+                                                      .colorAttachmentCount = 1,
+                                                      .pColorAttachments = &(VkAttachmentReference) {
+                                                              .attachment = 0,
+                                                              .layout = VK_IMAGE_LAYOUT_GENERAL,
+                                                      },
+                                                      .pResolveAttachments = NULL,
+                                                      .pDepthStencilAttachment = &(VkAttachmentReference) {
+                                                              .attachment = VK_ATTACHMENT_UNUSED,
+                                                              .layout = VK_IMAGE_LAYOUT_GENERAL,
+                                                      },
+                                                      .preserveAttachmentCount = 1,
+                                                      .pPreserveAttachments = (uint32_t[]) { 0 },
+                                              },
+                                                               .dependencyCount = 0,
+                                                                        }, &device->meta_state.alloc, pass);
+}
+
 static VkResult
 create_color_pipeline(struct radv_device *device,
-                      VkFormat vk_format,
                      uint32_t samples,
                       uint32_t frag_output,
                       struct radv_pipeline **pipeline,
-                     VkRenderPass *pass)
+                     VkRenderPass pass)
 {
        struct nir_shader *vs_nir;
        struct nir_shader *fs_nir;
@@ -270,44 +318,11 @@ create_color_pipeline(struct radv_device *device,
                .pAttachments = blend_attachment_state
        };
 
-       result = radv_CreateRenderPass(radv_device_to_handle(device),
-                                      &(VkRenderPassCreateInfo) {
-                                              .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
-                                                      .attachmentCount = 1,
-                                                      .pAttachments = &(VkAttachmentDescription) {
-                                                      .format = vk_format,
-                                                      .samples = samples,
-                                                      .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
-                                                      .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
-                                                      .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
-                                                      .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
-                                              },
-                                                      .subpassCount = 1,
-                                                               .pSubpasses = &(VkSubpassDescription) {
-                                                      .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
-                                                      .inputAttachmentCount = 0,
-                                                      .colorAttachmentCount = 1,
-                                                      .pColorAttachments = &(VkAttachmentReference) {
-                                                              .attachment = 0,
-                                                              .layout = VK_IMAGE_LAYOUT_GENERAL,
-                                                      },
-                                                      .pResolveAttachments = NULL,
-                                                      .pDepthStencilAttachment = &(VkAttachmentReference) {
-                                                              .attachment = VK_ATTACHMENT_UNUSED,
-                                                              .layout = VK_IMAGE_LAYOUT_GENERAL,
-                                                      },
-                                                      .preserveAttachmentCount = 1,
-                                                      .pPreserveAttachments = (uint32_t[]) { 0 },
-                                              },
-                                                               .dependencyCount = 0,
-                                                                        }, &device->meta_state.alloc, pass);
 
-       if (result != VK_SUCCESS)
-               return result;
        struct radv_graphics_pipeline_create_info extra = {
                .use_rectlist = true,
        };
-       result = create_pipeline(device, radv_render_pass_from_handle(*pass),
+       result = create_pipeline(device, radv_render_pass_from_handle(pass),
                                 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state,
                                 &extra, &device->meta_state.alloc, pipeline);
 
@@ -442,7 +457,7 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer,
                                           pipeline_h);
        }
 
-       radv_CmdDraw(cmd_buffer_h, 3, 1, 0, 0);
+       radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, 0);
 
        radv_cmd_buffer_set_subpass(cmd_buffer, subpass, false);
 }
@@ -472,6 +487,15 @@ build_depthstencil_shader(struct nir_shader **out_vs, struct nir_shader **out_fs
 
        nir_copy_var(&vs_b, vs_out_pos, vs_in_pos);
 
+       const struct glsl_type *layer_type = glsl_int_type();
+       nir_variable *vs_out_layer =
+               nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type,
+                                   "v_layer");
+       vs_out_layer->data.location = VARYING_SLOT_LAYER;
+       vs_out_layer->data.interpolation = INTERP_MODE_FLAT;
+       nir_ssa_def *inst_id = nir_load_system_value(&vs_b, nir_intrinsic_load_instance_id, 0);
+       nir_store_var(&vs_b, vs_out_layer, inst_id, 0x1);
+
        *out_vs = vs_b.shader;
        *out_fs = fs_b.shader;
 }
@@ -712,7 +736,7 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
        if (depth_view_can_fast_clear(iview, subpass->depth_stencil_attachment.layout, clear_rect))
                radv_set_depth_clear_regs(cmd_buffer, iview->image, clear_value, aspects);
 
-       radv_CmdDraw(cmd_buffer_h, 3, 1, 0, 0);
+       radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, 0);
 }
 
 
@@ -743,8 +767,14 @@ radv_device_init_meta_clear_state(struct radv_device *device)
                        VkFormat format = pipeline_formats[j];
                        unsigned fs_key = radv_format_meta_fs_key(format);
                        assert(!state->clear[i].color_pipelines[fs_key]);
-                       res = create_color_pipeline(device, format, samples, 0, &state->clear[i].color_pipelines[fs_key],
-                                                   &state->clear[i].render_pass[fs_key]);
+
+                       res = create_color_renderpass(device, format, samples,
+                                                     &state->clear[i].render_pass[fs_key]);
+                       if (res != VK_SUCCESS)
+                               goto fail;
+
+                       res = create_color_pipeline(device, samples, 0, &state->clear[i].color_pipelines[fs_key],
+                                                   state->clear[i].render_pass[fs_key]);
                        if (res != VK_SUCCESS)
                                goto fail;
 
@@ -796,7 +826,9 @@ fail:
 static bool
 emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer,
                      const VkClearAttachment *clear_att,
-                     const VkClearRect *clear_rect)
+                     const VkClearRect *clear_rect,
+                     enum radv_cmd_flush_bits *pre_flush,
+                     enum radv_cmd_flush_bits *post_flush)
 {
        const struct radv_subpass *subpass = cmd_buffer->state.subpass;
        const uint32_t subpass_att = clear_att->colorAttachment;
@@ -811,10 +843,10 @@ emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer,
        if (!iview->image->cmask.size && !iview->image->surface.dcc_size)
                return false;
 
-       if (!(cmd_buffer->device->debug_flags & RADV_DEBUG_FAST_CLEARS))
+       if (cmd_buffer->device->debug_flags & RADV_DEBUG_NO_FAST_CLEARS)
                return false;
 
-       if (!radv_layout_can_fast_clear(iview->image, image_layout, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index)))
+       if (!radv_layout_can_fast_clear(iview->image, image_layout, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index)))
                goto fail;
        if (vk_format_get_blocksizebits(iview->image->vk_format) > 64)
                goto fail;
@@ -854,9 +886,13 @@ emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer,
        if (ret == false)
                goto fail;
 
-       cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB |
-                                       RADV_CMD_FLAG_FLUSH_AND_INV_CB_META;
-       si_emit_cache_flush(cmd_buffer);
+       if (pre_flush) {
+               cmd_buffer->state.flush_bits |= (RADV_CMD_FLAG_FLUSH_AND_INV_CB |
+                                                RADV_CMD_FLAG_FLUSH_AND_INV_CB_META) & ~ *pre_flush;
+               *pre_flush |= cmd_buffer->state.flush_bits;
+       } else
+               cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB |
+                                               RADV_CMD_FLAG_FLUSH_AND_INV_CB_META;
        /* clear cmask buffer */
        if (iview->image->surface.dcc_size) {
                radv_fill_buffer(cmd_buffer, iview->image->bo,
@@ -867,9 +903,15 @@ emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer,
                                 iview->image->offset + iview->image->cmask.offset,
                                 iview->image->cmask.size, 0);
        }
-       cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH |
-                                       RADV_CMD_FLAG_INV_VMEM_L1 |
-                                       RADV_CMD_FLAG_INV_GLOBAL_L2;
+
+       if (post_flush)
+               *post_flush |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH |
+                              RADV_CMD_FLAG_INV_VMEM_L1 |
+                              RADV_CMD_FLAG_INV_GLOBAL_L2;
+       else
+               cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH |
+                                               RADV_CMD_FLAG_INV_VMEM_L1 |
+                                               RADV_CMD_FLAG_INV_GLOBAL_L2;
 
        radv_set_color_clear_regs(cmd_buffer, iview->image, subpass_att, clear_color);
 
@@ -884,11 +926,14 @@ fail:
 static void
 emit_clear(struct radv_cmd_buffer *cmd_buffer,
            const VkClearAttachment *clear_att,
-           const VkClearRect *clear_rect)
+           const VkClearRect *clear_rect,
+           enum radv_cmd_flush_bits *pre_flush,
+           enum radv_cmd_flush_bits *post_flush)
 {
        if (clear_att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
 
-               if (!emit_fast_color_clear(cmd_buffer, clear_att, clear_rect))
+               if (!emit_fast_color_clear(cmd_buffer, clear_att, clear_rect,
+                                          pre_flush, post_flush))
                        emit_color_clear(cmd_buffer, clear_att, clear_rect);
        } else {
                assert(clear_att->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT |
@@ -931,19 +976,18 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer)
 {
        struct radv_cmd_state *cmd_state = &cmd_buffer->state;
        struct radv_meta_saved_state saved_state;
+       enum radv_cmd_flush_bits pre_flush = 0;
+       enum radv_cmd_flush_bits post_flush = 0;
 
        if (!subpass_needs_clear(cmd_buffer))
                return;
 
        radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer);
 
-       if (cmd_state->framebuffer->layers > 1)
-               radv_finishme("clearing multi-layer framebuffer");
-
        VkClearRect clear_rect = {
                .rect = cmd_state->render_area,
                .baseArrayLayer = 0,
-               .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */
+               .layerCount = cmd_state->framebuffer->layers,
        };
 
        for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
@@ -961,7 +1005,7 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer)
                        .clearValue = cmd_state->attachments[a].clear_value,
                };
 
-               emit_clear(cmd_buffer, &clear_att, &clear_rect);
+               emit_clear(cmd_buffer, &clear_att, &clear_rect, &pre_flush, &post_flush);
                cmd_state->attachments[a].pending_clear_aspects = 0;
        }
 
@@ -976,12 +1020,14 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer)
                                .clearValue = cmd_state->attachments[ds].clear_value,
                        };
 
-                       emit_clear(cmd_buffer, &clear_att, &clear_rect);
+                       emit_clear(cmd_buffer, &clear_att, &clear_rect,
+                                  &pre_flush, &post_flush);
                        cmd_state->attachments[ds].pending_clear_aspects = 0;
                }
        }
 
        radv_meta_restore(&saved_state, cmd_buffer);
+       cmd_buffer->state.flush_bits |= post_flush;
 }
 
 static void
@@ -1102,7 +1148,7 @@ radv_clear_image_layer(struct radv_cmd_buffer *cmd_buffer,
                .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */
        };
 
-       emit_clear(cmd_buffer, &clear_att, &clear_rect);
+       emit_clear(cmd_buffer, &clear_att, &clear_rect, NULL, NULL);
 
        radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer));
        radv_DestroyRenderPass(device_h, pass,
@@ -1218,6 +1264,8 @@ void radv_CmdClearAttachments(
 {
        RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
        struct radv_meta_saved_state saved_state;
+       enum radv_cmd_flush_bits pre_flush = 0;
+       enum radv_cmd_flush_bits post_flush = 0;
 
        if (!cmd_buffer->state.subpass)
                return;
@@ -1229,9 +1277,10 @@ void radv_CmdClearAttachments(
         */
        for (uint32_t a = 0; a < attachmentCount; ++a) {
                for (uint32_t r = 0; r < rectCount; ++r) {
-                       emit_clear(cmd_buffer, &pAttachments[a], &pRects[r]);
+                       emit_clear(cmd_buffer, &pAttachments[a], &pRects[r], &pre_flush, &post_flush);
                }
        }
 
        radv_meta_restore(&saved_state, cmd_buffer);
+       cmd_buffer->state.flush_bits |= post_flush;
 }