blorp_batch_finish(&batch);
}
+static bool
+subpass_needs_clear(const struct anv_cmd_buffer *cmd_buffer)
+{
+ const struct anv_cmd_state *cmd_state = &cmd_buffer->state;
+ uint32_t ds = cmd_state->subpass->depth_stencil_attachment;
+
+ for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
+ uint32_t a = cmd_state->subpass->color_attachments[i];
+ if (cmd_state->attachments[a].pending_clear_aspects) {
+ return true;
+ }
+ }
+
+ if (ds != VK_ATTACHMENT_UNUSED &&
+ cmd_state->attachments[ds].pending_clear_aspects) {
+ return true;
+ }
+
+ return false;
+}
+
+void
+anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
+{
+ const struct anv_cmd_state *cmd_state = &cmd_buffer->state;
+
+ if (!subpass_needs_clear(cmd_buffer))
+ return;
+
+ /* Because this gets called within a render pass, we tell blorp not to
+ * trash our depth and stencil buffers.
+ */
+ struct blorp_batch batch;
+ blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer,
+ BLORP_BATCH_NO_EMIT_DEPTH_STENCIL);
+
+ VkClearRect clear_rect = {
+ .rect = cmd_buffer->state.render_area,
+ .baseArrayLayer = 0,
+ .layerCount = cmd_buffer->state.framebuffer->layers,
+ };
+
+ for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
+ const uint32_t a = cmd_state->subpass->color_attachments[i];
+
+ if (!cmd_state->attachments[a].pending_clear_aspects)
+ continue;
+
+ assert(cmd_state->attachments[a].pending_clear_aspects ==
+ VK_IMAGE_ASPECT_COLOR_BIT);
+
+ VkClearAttachment clear_att = {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .colorAttachment = i, /* Use attachment index relative to subpass */
+ .clearValue = cmd_state->attachments[a].clear_value,
+ };
+
+ clear_color_attachment(cmd_buffer, &batch, &clear_att, 1, &clear_rect);
+
+ cmd_state->attachments[a].pending_clear_aspects = 0;
+ }
+
+ const uint32_t ds = cmd_state->subpass->depth_stencil_attachment;
+
+ if (ds != VK_ATTACHMENT_UNUSED &&
+ cmd_state->attachments[ds].pending_clear_aspects) {
+
+ VkClearAttachment clear_att = {
+ .aspectMask = cmd_state->attachments[ds].pending_clear_aspects,
+ .clearValue = cmd_state->attachments[ds].clear_value,
+ };
+
+ clear_depth_stencil_attachment(cmd_buffer, &batch,
+ &clear_att, 1, &clear_rect);
+
+ cmd_state->attachments[ds].pending_clear_aspects = 0;
+ }
+
+ blorp_batch_finish(&batch);
+}
+
static void
resolve_image(struct blorp_batch *batch,
const struct anv_image *src_image,
};
static void
-meta_clear_begin(struct anv_meta_saved_state *saved_state,
- struct anv_cmd_buffer *cmd_buffer)
-{
- anv_meta_save(saved_state, cmd_buffer,
- (1 << VK_DYNAMIC_STATE_VIEWPORT) |
- (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;
-}
-
-static void
-meta_clear_end(struct anv_meta_saved_state *saved_state,
- struct anv_cmd_buffer *cmd_buffer)
-{
- anv_meta_restore(saved_state, cmd_buffer);
-}
-
-static void
build_color_shaders(struct nir_shader **out_vs,
struct nir_shader **out_fs,
uint32_t frag_output)
}
static void
-emit_color_clear(struct anv_cmd_buffer *cmd_buffer,
- const VkClearAttachment *clear_att,
- const VkClearRect *clear_rect)
-{
- struct anv_device *device = cmd_buffer->device;
- const struct anv_subpass *subpass = cmd_buffer->state.subpass;
- const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
- const uint32_t subpass_att = clear_att->colorAttachment;
- const uint32_t pass_att = subpass->color_attachments[subpass_att];
- const struct anv_image_view *iview = fb->attachments[pass_att];
- const uint32_t samples = iview->image->samples;
- const uint32_t samples_log2 = ffs(samples) - 1;
- struct anv_pipeline *pipeline =
- device->meta_state.clear[samples_log2].color_pipelines[subpass_att];
- VkClearColorValue clear_value = clear_att->clearValue.color;
-
- VkCommandBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
- VkPipeline pipeline_h = anv_pipeline_to_handle(pipeline);
-
- assert(samples_log2 < ARRAY_SIZE(device->meta_state.clear));
- assert(clear_att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
- assert(clear_att->colorAttachment < subpass->color_count);
-
- const struct color_clear_vattrs vertex_data[3] = {
- {
- .vue_header = { 0 },
- .position = {
- clear_rect->rect.offset.x,
- clear_rect->rect.offset.y,
- },
- .color = clear_value,
- },
- {
- .vue_header = { 0 },
- .position = {
- clear_rect->rect.offset.x + clear_rect->rect.extent.width,
- clear_rect->rect.offset.y,
- },
- .color = clear_value,
- },
- {
- .vue_header = { 0 },
- .position = {
- clear_rect->rect.offset.x + clear_rect->rect.extent.width,
- clear_rect->rect.offset.y + clear_rect->rect.extent.height,
- },
- .color = clear_value,
- },
- };
-
- struct anv_state state =
- anv_cmd_buffer_emit_dynamic(cmd_buffer, vertex_data, sizeof(vertex_data), 16);
-
- struct anv_buffer vertex_buffer = {
- .device = device,
- .size = sizeof(vertex_data),
- .bo = &device->dynamic_state_block_pool.bo,
- .offset = state.offset,
- };
-
- ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
- (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
- (VkDeviceSize[]) { 0 });
-
- if (cmd_buffer->state.pipeline != pipeline) {
- ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
- pipeline_h);
- }
-
- ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
-}
-
-
-static void
build_depthstencil_shader(struct nir_shader **out_vs)
{
nir_builder vs_b;
/*use_repclear*/ true, pipeline);
}
-static void
-emit_depthstencil_clear(struct anv_cmd_buffer *cmd_buffer,
- const VkClearAttachment *clear_att,
- const VkClearRect *clear_rect)
-{
- struct anv_device *device = cmd_buffer->device;
- struct anv_meta_state *meta_state = &device->meta_state;
- const struct anv_subpass *subpass = cmd_buffer->state.subpass;
- const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
- const uint32_t pass_att = subpass->depth_stencil_attachment;
- const struct anv_image_view *iview = fb->attachments[pass_att];
- const uint32_t samples = iview->image->samples;
- const uint32_t samples_log2 = ffs(samples) - 1;
- VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
- VkImageAspectFlags aspects = clear_att->aspectMask;
-
- VkCommandBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
-
- assert(samples_log2 < ARRAY_SIZE(meta_state->clear));
- assert(aspects == VK_IMAGE_ASPECT_DEPTH_BIT ||
- aspects == VK_IMAGE_ASPECT_STENCIL_BIT ||
- aspects == (VK_IMAGE_ASPECT_DEPTH_BIT |
- VK_IMAGE_ASPECT_STENCIL_BIT));
- assert(pass_att != VK_ATTACHMENT_UNUSED);
-
- const struct depthstencil_clear_vattrs vertex_data[3] = {
- {
- .vue_header = { 0 },
- .position = {
- clear_rect->rect.offset.x,
- clear_rect->rect.offset.y,
- },
- },
- {
- .vue_header = { 0 },
- .position = {
- clear_rect->rect.offset.x + clear_rect->rect.extent.width,
- clear_rect->rect.offset.y,
- },
- },
- {
- .vue_header = { 0 },
- .position = {
- clear_rect->rect.offset.x + clear_rect->rect.extent.width,
- clear_rect->rect.offset.y + clear_rect->rect.extent.height,
- },
- },
- };
-
- struct anv_state state =
- anv_cmd_buffer_emit_dynamic(cmd_buffer, vertex_data, sizeof(vertex_data), 16);
-
- struct anv_buffer vertex_buffer = {
- .device = device,
- .size = sizeof(vertex_data),
- .bo = &device->dynamic_state_block_pool.bo,
- .offset = state.offset,
- };
-
- ANV_CALL(CmdSetViewport)(cmd_buffer_h, 0, 1,
- (VkViewport[]) {
- {
- .x = 0,
- .y = 0,
- .width = fb->width,
- .height = fb->height,
-
- /* Ignored when clearing only stencil. */
- .minDepth = clear_value.depth,
- .maxDepth = clear_value.depth,
- },
- });
-
- if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
- ANV_CALL(CmdSetStencilReference)(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
- clear_value.stencil);
- }
-
- ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
- (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
- (VkDeviceSize[]) { 0 });
-
- struct anv_pipeline *pipeline;
- switch (aspects) {
- case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
- pipeline = meta_state->clear[samples_log2].depthstencil_pipeline;
- break;
- case VK_IMAGE_ASPECT_DEPTH_BIT:
- pipeline = meta_state->clear[samples_log2].depth_only_pipeline;
- break;
- case VK_IMAGE_ASPECT_STENCIL_BIT:
- pipeline = meta_state->clear[samples_log2].stencil_only_pipeline;
- break;
- default:
- unreachable("expected depth or stencil aspect");
- }
-
- if (cmd_buffer->state.pipeline != pipeline) {
- ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
- anv_pipeline_to_handle(pipeline));
- }
-
- ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
-}
-
VkResult
anv_device_init_meta_clear_state(struct anv_device *device)
{
anv_device_finish_meta_clear_state(device);
return res;
}
-
-/**
- * The parameters mean that same as those in vkCmdClearAttachments.
- */
-static void
-emit_clear(struct anv_cmd_buffer *cmd_buffer,
- const VkClearAttachment *clear_att,
- const VkClearRect *clear_rect)
-{
- if (clear_att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
- emit_color_clear(cmd_buffer, clear_att, clear_rect);
- } else {
- assert(clear_att->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT |
- VK_IMAGE_ASPECT_STENCIL_BIT));
- emit_depthstencil_clear(cmd_buffer, clear_att, clear_rect);
- }
-}
-
-static bool
-subpass_needs_clear(const struct anv_cmd_buffer *cmd_buffer)
-{
- const struct anv_cmd_state *cmd_state = &cmd_buffer->state;
- uint32_t ds = cmd_state->subpass->depth_stencil_attachment;
-
- for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
- uint32_t a = cmd_state->subpass->color_attachments[i];
- if (cmd_state->attachments[a].pending_clear_aspects) {
- return true;
- }
- }
-
- if (ds != VK_ATTACHMENT_UNUSED &&
- cmd_state->attachments[ds].pending_clear_aspects) {
- return true;
- }
-
- return false;
-}
-
-/**
- * Emit any pending attachment clears for the current subpass.
- *
- * @see anv_attachment_state::pending_clear_aspects
- */
-void
-anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
-{
- struct anv_cmd_state *cmd_state = &cmd_buffer->state;
- struct anv_meta_saved_state saved_state;
-
- if (!subpass_needs_clear(cmd_buffer))
- return;
-
- meta_clear_begin(&saved_state, cmd_buffer);
-
- if (cmd_state->framebuffer->layers > 1)
- anv_finishme("clearing multi-layer framebuffer");
-
- VkClearRect clear_rect = {
- .rect = cmd_state->render_area,
- .baseArrayLayer = 0,
- .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */
- };
-
- for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
- uint32_t a = cmd_state->subpass->color_attachments[i];
-
- if (!cmd_state->attachments[a].pending_clear_aspects)
- continue;
-
- assert(cmd_state->attachments[a].pending_clear_aspects ==
- VK_IMAGE_ASPECT_COLOR_BIT);
-
- VkClearAttachment clear_att = {
- .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
- .colorAttachment = i, /* Use attachment index relative to subpass */
- .clearValue = cmd_state->attachments[a].clear_value,
- };
-
- emit_clear(cmd_buffer, &clear_att, &clear_rect);
- cmd_state->attachments[a].pending_clear_aspects = 0;
- }
-
- uint32_t ds = cmd_state->subpass->depth_stencil_attachment;
-
- if (ds != VK_ATTACHMENT_UNUSED &&
- cmd_state->attachments[ds].pending_clear_aspects) {
-
- VkClearAttachment clear_att = {
- .aspectMask = cmd_state->attachments[ds].pending_clear_aspects,
- .clearValue = cmd_state->attachments[ds].clear_value,
- };
-
- emit_clear(cmd_buffer, &clear_att, &clear_rect);
- cmd_state->attachments[ds].pending_clear_aspects = 0;
- }
-
- meta_clear_end(&saved_state, cmd_buffer);
-}