anv/clear: Handle ClearImage on 3-D images
[mesa.git] / src / intel / vulkan / anv_meta_clear.c
index 739ae09582c41ea13a4fb8c1eaf19db11c0e6972..fe750c859f8f2117eeae37963128fb7e528286c9 100644 (file)
@@ -44,11 +44,11 @@ meta_clear_begin(struct anv_meta_saved_state *saved_state,
 {
    anv_meta_save(saved_state, cmd_buffer,
                  (1 << VK_DYNAMIC_STATE_VIEWPORT) |
-                 (1 << VK_DYNAMIC_STATE_SCISSOR) |
-                 (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE));
+                 (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE) |
+                 (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK));
 
+   /* Avoid uploading more viewport states than necessary */
    cmd_buffer->state.dynamic.viewport.count = 0;
-   cmd_buffer->state.dynamic.scissor.count = 0;
 }
 
 static void
@@ -191,8 +191,9 @@ create_pipeline(struct anv_device *device,
              * we need only restore dynamic state was vkCmdSet.
              */
             .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
-            .dynamicStateCount = 9,
+            .dynamicStateCount = 8,
             .pDynamicStates = (VkDynamicState[]) {
+               /* Everything except stencil write mask */
                VK_DYNAMIC_STATE_VIEWPORT,
                VK_DYNAMIC_STATE_SCISSOR,
                VK_DYNAMIC_STATE_LINE_WIDTH,
@@ -200,7 +201,6 @@ create_pipeline(struct anv_device *device,
                VK_DYNAMIC_STATE_BLEND_CONSTANTS,
                VK_DYNAMIC_STATE_DEPTH_BOUNDS,
                VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
-               VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
                VK_DYNAMIC_STATE_STENCIL_REFERENCE,
             },
          },
@@ -211,7 +211,6 @@ create_pipeline(struct anv_device *device,
       &(struct anv_graphics_pipeline_create_info) {
          .color_attachment_count = MAX_RTS,
          .use_repclear = use_repclear,
-         .disable_viewport = true,
          .disable_vs = true,
          .use_rectlist = true
       },
@@ -296,14 +295,15 @@ create_color_pipeline(struct anv_device *device,
       .pAttachments = blend_attachment_state
    };
 
-   /* Disable repclear because we do not want the compiler to replace the
-    * shader. We need the shader to write to the specified color attachment,
-    * but the repclear shader writes to all color attachments.
+   /* Use the repclear shader.  Since the NIR shader we are providing has
+    * exactly one output, that output will get compacted down to binding
+    * table entry 0.  The hard-coded repclear shader is then exactly what
+    * we want regardless of what attachment we are actually clearing.
     */
    return
       create_pipeline(device, samples, vs_nir, fs_nir, &vi_state, &ds_state,
                       &cb_state, &device->meta_state.alloc,
-                      /*use_repclear*/ false, pipeline);
+                      /*use_repclear*/ true, pipeline);
 }
 
 static void
@@ -394,26 +394,6 @@ emit_color_clear(struct anv_cmd_buffer *cmd_buffer,
       .offset = state.offset,
    };
 
-   ANV_CALL(CmdSetViewport)(cmd_buffer_h, 0, 1,
-      (VkViewport[]) {
-         {
-            .x = 0,
-            .y = 0,
-            .width = fb->width,
-            .height = fb->height,
-            .minDepth = 0.0,
-            .maxDepth = 1.0,
-         },
-      });
-
-   ANV_CALL(CmdSetScissor)(cmd_buffer_h, 0, 1,
-      (VkRect2D[]) {
-         {
-            .offset = { 0, 0 },
-            .extent = { fb->width, fb->height },
-         }
-      });
-
    ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
       (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
       (VkDeviceSize[]) { 0 });
@@ -593,14 +573,6 @@ emit_depthstencil_clear(struct anv_cmd_buffer *cmd_buffer,
          },
       });
 
-   ANV_CALL(CmdSetScissor)(cmd_buffer_h, 0, 1,
-      (VkRect2D[]) {
-         {
-            .offset = { 0, 0 },
-            .extent = { fb->width, fb->height },
-         }
-      });
-
    if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
       ANV_CALL(CmdSetStencilReference)(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
                                        clear_value.stencil);
@@ -725,7 +697,6 @@ void
 anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
 {
    struct anv_cmd_state *cmd_state = &cmd_buffer->state;
-   struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
    struct anv_meta_saved_state saved_state;
 
    if (!subpass_needs_clear(cmd_buffer))
@@ -737,10 +708,7 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
       anv_finishme("clearing multi-layer framebuffer");
 
    VkClearRect clear_rect = {
-      .rect = {
-         .offset = { 0, 0 },
-         .extent = { fb->width, fb->height },
-      },
+      .rect = cmd_state->render_area,
       .baseArrayLayer = 0,
       .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */
    };
@@ -793,9 +761,11 @@ anv_cmd_clear_image(struct anv_cmd_buffer *cmd_buffer,
 
    for (uint32_t r = 0; r < range_count; r++) {
       const VkImageSubresourceRange *range = &ranges[r];
-
-      for (uint32_t l = 0; l < range->levelCount; ++l) {
-         for (uint32_t s = 0; s < range->layerCount; ++s) {
+      for (uint32_t l = 0; l < anv_get_levelCount(image, range); ++l) {
+         const uint32_t layer_count = image->type == VK_IMAGE_TYPE_3D ?
+                                      anv_minify(image->extent.depth, l) :
+                                      anv_get_layerCount(image, range);
+         for (uint32_t s = 0; s < layer_count; ++s) {
             struct anv_image_view iview;
             anv_image_view_init(&iview, cmd_buffer->device,
                &(VkImageViewCreateInfo) {
@@ -811,7 +781,7 @@ anv_cmd_clear_image(struct anv_cmd_buffer *cmd_buffer,
                      .layerCount = 1
                   },
                },
-               cmd_buffer, 0);
+               cmd_buffer, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
 
             VkFramebuffer fb;
             anv_CreateFramebuffer(device_h,