diff options
-rw-r--r-- | src/intel/vulkan/anv_image.c | 17 | ||||
-rw-r--r-- | src/intel/vulkan/anv_private.h | 5 | ||||
-rw-r--r-- | src/intel/vulkan/genX_cmd_buffer.c | 52 |
3 files changed, 70 insertions, 4 deletions
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index d9b5d266020..da4601ce20e 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -1059,6 +1059,13 @@ anv_image_fill_surface_state(struct anv_device *device, const uint64_t aux_address = aux_usage == ISL_AUX_USAGE_NONE ? 0 : (image->planes[plane].bo_offset + aux_surface->offset); + struct anv_address clear_address = { .bo = NULL }; + state_inout->clear_address = 0; + if (device->info.gen >= 10 && aux_usage != ISL_AUX_USAGE_NONE && + aux_usage != ISL_AUX_USAGE_HIZ) { + clear_address = anv_image_get_clear_color_addr(device, image, aspect); + } + if (view_usage == ISL_SURF_USAGE_STORAGE_BIT && !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY) && !isl_has_matching_typed_storage_image_format(&device->info, @@ -1076,6 +1083,7 @@ anv_image_fill_surface_state(struct anv_device *device, .mocs = device->default_mocs); state_inout->address = address, state_inout->aux_address = 0; + state_inout->clear_address = 0; } else { if (view_usage == ISL_SURF_USAGE_STORAGE_BIT && !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY)) { @@ -1149,6 +1157,8 @@ anv_image_fill_surface_state(struct anv_device *device, .aux_surf = &aux_surface->isl, .aux_usage = aux_usage, .aux_address = aux_address, + .clear_address = clear_address.offset, + .use_clear_address = clear_address.bo != NULL, .mocs = device->default_mocs, .x_offset_sa = tile_x_sa, .y_offset_sa = tile_y_sa); @@ -1163,6 +1173,13 @@ anv_image_fill_surface_state(struct anv_device *device, assert((aux_address & 0xfff) == 0); assert(aux_address == (*aux_addr_dw & 0xfffff000)); state_inout->aux_address = *aux_addr_dw; + + if (device->info.gen >= 10 && clear_address.bo) { + uint32_t *clear_addr_dw = state_inout->state.map + + device->isl_dev.ss.clear_color_state_offset; + assert((clear_address.offset & 0x3f) == 0); + state_inout->clear_address = *clear_addr_dw; + } } anv_state_flush(device, state_inout->state); diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index b2d8079f3c9..989842ef236 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1704,6 +1704,11 @@ struct anv_surface_state { * gen8, the bottom 12 bits of this address include extra aux information. */ uint64_t aux_address; + /* Address of the clear color, if any + * + * This address is relative to the start of the BO. + */ + uint64_t clear_address; }; /** diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 5e5e2bbd6fe..1a08b5eaff5 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -200,6 +200,17 @@ add_image_view_relocs(struct anv_cmd_buffer *cmd_buffer, if (result != VK_SUCCESS) anv_batch_set_error(&cmd_buffer->batch, result); } + + if (state.clear_address) { + VkResult result = + anv_reloc_list_add(&cmd_buffer->surface_relocs, + &cmd_buffer->pool->alloc, + state.state.offset + + isl_dev->ss.clear_color_state_offset, + image->planes[image_plane].bo, state.clear_address); + if (result != VK_SUCCESS) + anv_batch_set_error(&cmd_buffer->batch, result); + } } static void @@ -1124,6 +1135,34 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT; } +static void +update_fast_clear_color(struct anv_cmd_buffer *cmd_buffer, + const struct anv_attachment_state *att_state, + const struct anv_image_view *iview) +{ + assert(GEN_GEN >= 10); + assert(iview->image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); + + struct anv_address clear_address = + anv_image_get_clear_color_addr(cmd_buffer->device, iview->image, + VK_IMAGE_ASPECT_COLOR_BIT); + union isl_color_value clear_color; + anv_clear_color_from_att_state(&clear_color, att_state, iview); + + /* Clear values are stored at the same bo as the aux surface, right + * after the surface. + */ + for (int i = 0; i < 4; i++) { + anv_batch_emit(&cmd_buffer->batch, GENX(MI_STORE_DATA_IMM), sdi) { + sdi.Address = (struct anv_address) { + .bo = clear_address.bo, + .offset = clear_address.offset + i * 4, + }; + sdi.ImmediateData = clear_color.u32[i]; + } + } +} + /** * Setup anv_cmd_state::attachments for vkCmdBeginRenderPass. */ @@ -3567,9 +3606,13 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer, if (is_multiview) att_state->pending_clear_views &= ~1; - genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state, - image, VK_IMAGE_ASPECT_COLOR_BIT, - true /* copy from ss */); + if (GEN_GEN < 10) { + genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state, + image, VK_IMAGE_ASPECT_COLOR_BIT, + true /* copy from ss */); + } else { + update_fast_clear_color(cmd_buffer, att_state, iview); + } if (att_state->clear_color_is_zero) { /* This image has the auxiliary buffer enabled. We can mark the @@ -3681,7 +3724,8 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer, assert(att_state->pending_clear_aspects == 0); } - if ((att_state->pending_load_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && + if (GEN_GEN < 10 && + (att_state->pending_load_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->planes[0].aux_surface.isl.size > 0 && iview->planes[0].isl.base_level == 0 && iview->planes[0].isl.base_array_layer == 0) { |