case 9:
device->blorp.exec = gen9_blorp_exec;
break;
+ case 10:
+ device->blorp.exec = gen10_blorp_exec;
+ break;
default:
unreachable("Unknown hardware generation");
}
* little data at the top to build its linked list.
*/
const uint32_t max_update_size =
- cmd_buffer->device->dynamic_state_block_pool.block_size - 64;
+ cmd_buffer->device->dynamic_state_pool.block_size - 64;
assert(max_update_size < MAX_SURFACE_DIM * 4);
bs = gcd_pow2_u64(bs, copy_size);
do_buffer_copy(&batch,
- &cmd_buffer->device->dynamic_state_block_pool.bo,
+ &cmd_buffer->device->dynamic_state_pool.block_pool.bo,
tmp_data.offset,
dst_buffer->bo, dst_buffer->offset + dstOffset,
copy_size / bs, 1, bs);
union isl_color_value clear_color =
vk_to_isl_color(attachment->clearValue.color);
+ /* If multiview is enabled we ignore baseArrayLayer and layerCount */
+ if (subpass->view_mask) {
+ uint32_t view_idx;
+ for_each_bit(view_idx, subpass->view_mask) {
+ for (uint32_t r = 0; r < rectCount; ++r) {
+ const VkOffset2D offset = pRects[r].rect.offset;
+ const VkExtent2D extent = pRects[r].rect.extent;
+ blorp_clear_attachments(batch, binding_table,
+ ISL_FORMAT_UNSUPPORTED, pass_att->samples,
+ view_idx, 1,
+ offset.x, offset.y,
+ offset.x + extent.width,
+ offset.y + extent.height,
+ true, clear_color, false, 0.0f, 0, 0);
+ }
+ }
+ return;
+ }
+
for (uint32_t r = 0; r < rectCount; ++r) {
const VkOffset2D offset = pRects[r].rect.offset;
const VkExtent2D extent = pRects[r].rect.extent;
if (result != VK_SUCCESS)
return;
+ /* If multiview is enabled we ignore baseArrayLayer and layerCount */
+ if (subpass->view_mask) {
+ uint32_t view_idx;
+ for_each_bit(view_idx, subpass->view_mask) {
+ for (uint32_t r = 0; r < rectCount; ++r) {
+ const VkOffset2D offset = pRects[r].rect.offset;
+ const VkExtent2D extent = pRects[r].rect.extent;
+ VkClearDepthStencilValue value = attachment->clearValue.depthStencil;
+ blorp_clear_attachments(batch, binding_table,
+ depth_format, pass_att->samples,
+ view_idx, 1,
+ offset.x, offset.y,
+ offset.x + extent.width,
+ offset.y + extent.height,
+ false, color_value,
+ clear_depth, value.depth,
+ clear_stencil ? 0xff : 0, value.stencil);
+ }
+ }
+ return;
+ }
+
for (uint32_t r = 0; r < rectCount; ++r) {
const VkOffset2D offset = pRects[r].rect.offset;
const VkExtent2D extent = pRects[r].rect.extent;
clear_depth, clear_stencil,
clear_att.clearValue.
depthStencil.stencil);
+
+ /* From the SKL PRM, Depth Buffer Clear:
+ *
+ * Depth Buffer Clear Workaround
+ * Depth buffer clear pass using any of the methods (WM_STATE,
+ * 3DSTATE_WM or 3DSTATE_WM_HZ_OP) must be followed by a
+ * PIPE_CONTROL command with DEPTH_STALL bit and Depth FLUSH bits
+ * “set” before starting to render. DepthStall and DepthFlush are
+ * not needed between consecutive depth clear passes nor is it
+ * required if the depth-clear pass was done with “full_surf_clear”
+ * bit set in the 3DSTATE_WM_HZ_OP.
+ */
+ if (clear_depth) {
+ cmd_buffer->state.pending_pipe_bits |=
+ ANV_PIPE_DEPTH_CACHE_FLUSH_BIT | ANV_PIPE_DEPTH_STALL_BIT;
+ }
}
}
blorp_batch_finish(&batch);
}
+void
+anv_image_ccs_clear(struct anv_cmd_buffer *cmd_buffer,
+ const struct anv_image *image,
+ const uint32_t base_level, const uint32_t level_count,
+ const uint32_t base_layer, uint32_t layer_count)
+{
+ assert(image->type == VK_IMAGE_TYPE_3D || image->extent.depth == 1);
+
+ if (image->type == VK_IMAGE_TYPE_3D) {
+ assert(base_layer == 0);
+ assert(layer_count == anv_minify(image->extent.depth, base_level));
+ }
+
+ struct blorp_batch batch;
+ blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
+
+ struct blorp_surf surf;
+ get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT,
+ image->aux_usage, &surf);
+
+ /* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear":
+ *
+ * "After Render target fast clear, pipe-control with color cache
+ * write-flush must be issued before sending any DRAW commands on
+ * that render target."
+ *
+ * This comment is a bit cryptic and doesn't really tell you what's going
+ * or what's really needed. It appears that fast clear ops are not
+ * properly synchronized with other drawing. This means that we cannot
+ * have a fast clear operation in the pipe at the same time as other
+ * regular drawing operations. We need to use a PIPE_CONTROL to ensure
+ * that the contents of the previous draw hit the render target before we
+ * resolve and then use a second PIPE_CONTROL after the resolve to ensure
+ * that it is completed before any additional drawing occurs.
+ */
+ cmd_buffer->state.pending_pipe_bits |=
+ ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
+
+ for (uint32_t l = 0; l < level_count; l++) {
+ const uint32_t level = base_level + l;
+
+ const VkExtent3D extent = {
+ .width = anv_minify(image->extent.width, level),
+ .height = anv_minify(image->extent.height, level),
+ .depth = anv_minify(image->extent.depth, level),
+ };
+
+ if (image->type == VK_IMAGE_TYPE_3D)
+ layer_count = extent.depth;
+
+ assert(level < anv_image_aux_levels(image));
+ assert(base_layer + layer_count <= anv_image_aux_layers(image, level));
+ blorp_fast_clear(&batch, &surf, surf.surf->format,
+ level, base_layer, layer_count,
+ 0, 0, extent.width, extent.height);
+ }
+
+ cmd_buffer->state.pending_pipe_bits |=
+ ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
+}
+
static void
ccs_resolve_attachment(struct anv_cmd_buffer *cmd_buffer,
- struct blorp_batch *batch,
uint32_t att)
{
struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
if (resolve_op == BLORP_FAST_CLEAR_OP_NONE)
return;
- struct blorp_surf surf;
- get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT,
- att_state->aux_usage, &surf);
- if (att_state->fast_clear)
- surf.clear_color = vk_to_isl_color(att_state->clear_value.color);
-
/* From the Sky Lake PRM Vol. 7, "Render Target Resolve":
*
* "When performing a render target resolve, PIPE_CONTROL with end of
cmd_buffer->state.pending_pipe_bits |=
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
- for (uint32_t layer = 0; layer < fb->layers; layer++) {
- blorp_ccs_resolve(batch, &surf,
- iview->isl.base_level,
- iview->isl.base_array_layer + layer,
- iview->isl.format, resolve_op);
- }
+ anv_ccs_resolve(cmd_buffer, att_state->color_rt_state, image,
+ iview->isl.base_level, fb->layers, resolve_op);
cmd_buffer->state.pending_pipe_bits |=
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
struct anv_subpass *subpass = cmd_buffer->state.subpass;
- struct blorp_batch batch;
- blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
-
for (uint32_t i = 0; i < subpass->color_count; ++i) {
const uint32_t att = subpass->color_attachments[i].attachment;
if (att == VK_ATTACHMENT_UNUSED)
continue;
assert(att < cmd_buffer->state.pass->attachment_count);
- ccs_resolve_attachment(cmd_buffer, &batch, att);
+ ccs_resolve_attachment(cmd_buffer, att);
}
if (subpass->has_resolve) {
const VkRect2D render_area = cmd_buffer->state.render_area;
assert(src_iview->aspect_mask == dst_iview->aspect_mask);
+
+ struct blorp_batch batch;
+ blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
+
resolve_image(&batch, src_iview->image,
src_iview->isl.base_level,
src_iview->isl.base_array_layer,
render_area.offset.x, render_area.offset.y,
render_area.extent.width, render_area.extent.height);
- ccs_resolve_attachment(cmd_buffer, &batch, dst_att);
+ blorp_batch_finish(&batch);
+
+ ccs_resolve_attachment(cmd_buffer, dst_att);
}
}
- blorp_batch_finish(&batch);
}
void
};
surf.aux_usage = ISL_AUX_USAGE_HIZ;
- surf.clear_color.u32[0] = (uint32_t) ANV_HZ_FC_VAL;
+ surf.clear_color.f32[0] = ANV_HZ_FC_VAL;
+
+ blorp_hiz_op(&batch, &surf, 0, 0, 1, op);
+ blorp_batch_finish(&batch);
+}
+
+void
+anv_ccs_resolve(struct anv_cmd_buffer * const cmd_buffer,
+ const struct anv_state surface_state,
+ const struct anv_image * const image,
+ const uint8_t level, const uint32_t layer_count,
+ const enum blorp_fast_clear_op op)
+{
+ assert(cmd_buffer && image);
+
+ /* The resolved subresource range must have a CCS buffer. */
+ assert(level < anv_image_aux_levels(image));
+ assert(layer_count <= anv_image_aux_layers(image, level));
+ assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT && image->samples == 1);
+
+ /* Create a binding table for this surface state. */
+ uint32_t binding_table;
+ VkResult result =
+ binding_table_for_surface_state(cmd_buffer, surface_state,
+ &binding_table);
+ if (result != VK_SUCCESS)
+ return;
+
+ struct blorp_batch batch;
+ blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
+
+ struct blorp_surf surf;
+ get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT,
+ image->aux_usage == ISL_AUX_USAGE_CCS_E ?
+ ISL_AUX_USAGE_CCS_E : ISL_AUX_USAGE_CCS_D,
+ &surf);
+
+ blorp_ccs_resolve_attachment(&batch, binding_table, &surf, level,
+ layer_count, image->color_surface.isl.format,
+ op);
- blorp_gen6_hiz_op(&batch, &surf, 0, 0, op);
blorp_batch_finish(&batch);
}