From 22e6858b2b1c76463072393412fb5085bb4ed157 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 11 Jul 2017 10:06:36 -0700 Subject: [PATCH] anv/image: Break surface state fill logic into a helper This gives us a single centralized place where we take an image view and use it to fill out a surface state. Reviewed-by: Lionel Landwerlin --- src/intel/vulkan/anv_image.c | 173 +++++++++++++++++++++---------------- src/intel/vulkan/anv_private.h | 16 ++++ src/intel/vulkan/genX_cmd_buffer.c | 74 ++++++++-------- 3 files changed, 151 insertions(+), 112 deletions(-) diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index c3057e2..f8cb243 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -712,6 +712,79 @@ remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component, } } +void +anv_image_fill_surface_state(struct anv_device *device, + const struct anv_image *image, + VkImageAspectFlagBits aspect, + const struct isl_view *view_in, + isl_surf_usage_flags_t view_usage, + enum isl_aux_usage aux_usage, + const union isl_color_value *clear_color, + enum anv_image_view_state_flags flags, + struct anv_state *state, + struct brw_image_param *image_param_out) +{ + const struct anv_surface *surface = + anv_image_get_surface_for_aspect_mask(image, aspect); + + struct isl_view view = *view_in; + view.usage |= view_usage; + + if (view_usage == ISL_SURF_USAGE_RENDER_TARGET_BIT) + view.swizzle = anv_swizzle_for_render(view.swizzle); + + /* If this is a HiZ buffer we can sample from with a programmable clear + * value (SKL+), define the clear value to the optimal constant. + */ + union isl_color_value default_clear_color = { .u32 = { 0, } }; + if (device->info.gen >= 9 && aux_usage == ISL_AUX_USAGE_HIZ) + default_clear_color.f32[0] = ANV_HZ_FC_VAL; + if (!clear_color) + clear_color = &default_clear_color; + + 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, + view.format)) { + /* In this case, we are a writeable storage buffer which needs to be + * lowered to linear. All tiling and offset calculations will be done in + * the shader. + */ + assert(aux_usage == ISL_AUX_USAGE_NONE); + isl_buffer_fill_state(&device->isl_dev, state->map, + .size = surface->isl.size, + .format = ISL_FORMAT_RAW, + .stride = 1, + .mocs = device->default_mocs); + } else { + if (view_usage == ISL_SURF_USAGE_STORAGE_BIT && + !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY)) { + /* Typed surface reads support a very limited subset of the shader + * image formats. Translate it into the closest format the hardware + * supports. + */ + assert(aux_usage == ISL_AUX_USAGE_NONE); + view.format = isl_lower_storage_image_format(&device->info, + view.format); + } + + isl_surf_fill_state(&device->isl_dev, state->map, + .surf = &surface->isl, + .view = &view, + .clear_color = *clear_color, + .aux_surf = &image->aux_surface.isl, + .aux_usage = aux_usage, + .mocs = device->default_mocs); + } + + anv_state_flush(device, *state); + + if (image_param_out) { + assert(view_usage == ISL_SURF_USAGE_STORAGE_BIT); + isl_surf_fill_image_param(&device->isl_dev, image_param_out, + &surface->isl, &view); + } +} VkResult anv_CreateImageView(VkDevice _device, @@ -825,37 +898,19 @@ anv_CreateImageView(VkDevice _device, anv_layout_to_aux_usage(&device->info, image, iview->aspect_mask, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - /* If this is a HiZ buffer we can sample from with a programmable clear - * value (SKL+), define the clear value to the optimal constant. - */ - union isl_color_value clear_color = { .u32 = { 0, } }; - if ((iview->aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) && - device->info.gen >= 9) - clear_color.f32[0] = ANV_HZ_FC_VAL; - - struct isl_view view = iview->isl; - view.usage |= ISL_SURF_USAGE_TEXTURE_BIT; - - isl_surf_fill_state(&device->isl_dev, - iview->optimal_sampler_surface_state.map, - .surf = &surface->isl, - .view = &view, - .clear_color = clear_color, - .aux_surf = &image->aux_surface.isl, - .aux_usage = iview->optimal_sampler_aux_usage, - .mocs = device->default_mocs); - - isl_surf_fill_state(&device->isl_dev, - iview->general_sampler_surface_state.map, - .surf = &surface->isl, - .view = &view, - .clear_color = clear_color, - .aux_surf = &image->aux_surface.isl, - .aux_usage = iview->general_sampler_aux_usage, - .mocs = device->default_mocs); - - anv_state_flush(device, iview->optimal_sampler_surface_state); - anv_state_flush(device, iview->general_sampler_surface_state); + anv_image_fill_surface_state(device, image, iview->aspect_mask, + &iview->isl, ISL_SURF_USAGE_TEXTURE_BIT, + iview->optimal_sampler_aux_usage, NULL, + ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL, + &iview->optimal_sampler_surface_state, + NULL); + + anv_image_fill_surface_state(device, image, iview->aspect_mask, + &iview->isl, ISL_SURF_USAGE_TEXTURE_BIT, + iview->general_sampler_aux_usage, NULL, + 0, + &iview->general_sampler_surface_state, + NULL); } /* NOTE: This one needs to go last since it may stomp isl_view.format */ @@ -863,49 +918,19 @@ anv_CreateImageView(VkDevice _device, iview->storage_surface_state = alloc_surface_state(device); iview->writeonly_storage_surface_state = alloc_surface_state(device); - struct isl_view view = iview->isl; - view.usage |= ISL_SURF_USAGE_STORAGE_BIT; - - /* Write-only accesses always used a typed write instruction and should - * therefore use the real format. - */ - isl_surf_fill_state(&device->isl_dev, - iview->writeonly_storage_surface_state.map, - .surf = &surface->isl, - .view = &view, - .aux_surf = &image->aux_surface.isl, - .aux_usage = image->aux_usage, - .mocs = device->default_mocs); - - if (isl_has_matching_typed_storage_image_format(&device->info, - format.isl_format)) { - /* Typed surface reads support a very limited subset of the shader - * image formats. Translate it into the closest format the hardware - * supports. - */ - view.format = isl_lower_storage_image_format(&device->info, - format.isl_format); - - isl_surf_fill_state(&device->isl_dev, - iview->storage_surface_state.map, - .surf = &surface->isl, - .view = &view, - .aux_surf = &image->aux_surface.isl, - .aux_usage = image->aux_usage, - .mocs = device->default_mocs); - } else { - anv_fill_buffer_surface_state(device, iview->storage_surface_state, - ISL_FORMAT_RAW, - iview->offset, - iview->bo->size - iview->offset, 1); - } - - isl_surf_fill_image_param(&device->isl_dev, - &iview->storage_image_param, - &surface->isl, &iview->isl); - - anv_state_flush(device, iview->storage_surface_state); - anv_state_flush(device, iview->writeonly_storage_surface_state); + anv_image_fill_surface_state(device, image, iview->aspect_mask, + &iview->isl, ISL_SURF_USAGE_STORAGE_BIT, + ISL_AUX_USAGE_NONE, NULL, + 0, + &iview->storage_surface_state, + &iview->storage_image_param); + + anv_image_fill_surface_state(device, image, iview->aspect_mask, + &iview->isl, ISL_SURF_USAGE_STORAGE_BIT, + ISL_AUX_USAGE_NONE, NULL, + ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY, + &iview->writeonly_storage_surface_state, + NULL); } *pView = anv_image_view_to_handle(iview); diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index df8de8d..ee7672f 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2393,6 +2393,22 @@ struct anv_image_view { struct brw_image_param storage_image_param; }; +enum anv_image_view_state_flags { + ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY = (1 << 0), + ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL = (1 << 1), +}; + +void anv_image_fill_surface_state(struct anv_device *device, + const struct anv_image *image, + VkImageAspectFlagBits aspect, + const struct isl_view *view, + isl_surf_usage_flags_t view_usage, + enum isl_aux_usage aux_usage, + const union isl_color_value *clear_color, + enum anv_image_view_state_flags flags, + struct anv_state *state, + struct brw_image_param *image_param_out); + struct anv_image_create_info { const VkImageCreateInfo *vk_info; diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index a16f67b..188d9e7 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -768,26 +768,27 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, genX(load_needs_resolve_predicate)(cmd_buffer, image, level); + enum isl_aux_usage aux_usage = image->aux_usage == ISL_AUX_USAGE_NONE ? + ISL_AUX_USAGE_CCS_D : image->aux_usage; + /* Create a surface state with the right clear color and perform the * resolve. */ struct anv_state surface_state = anv_cmd_buffer_alloc_surface_state(cmd_buffer); - isl_surf_fill_state(&cmd_buffer->device->isl_dev, surface_state.map, - .surf = &image->color_surface.isl, - .view = &(struct isl_view) { - .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT, - .format = image->color_surface.isl.format, - .swizzle = ISL_SWIZZLE_IDENTITY, - .base_level = level, - .levels = 1, - .base_array_layer = base_layer, - .array_len = layer_count, - }, - .aux_surf = &image->aux_surface.isl, - .aux_usage = image->aux_usage == ISL_AUX_USAGE_NONE ? - ISL_AUX_USAGE_CCS_D : image->aux_usage, - .mocs = cmd_buffer->device->default_mocs); + anv_image_fill_surface_state(cmd_buffer->device, + image, VK_IMAGE_ASPECT_COLOR_BIT, + &(struct isl_view) { + .format = image->color_surface.isl.format, + .swizzle = ISL_SWIZZLE_IDENTITY, + .base_level = level, + .levels = 1, + .base_array_layer = base_layer, + .array_len = layer_count, + }, + ISL_SURF_USAGE_RENDER_TARGET_BIT, + aux_usage, NULL, 0, + &surface_state, NULL); add_image_relocs(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT, image->aux_usage == ISL_AUX_USAGE_CCS_E ? ISL_AUX_USAGE_CCS_E : ISL_AUX_USAGE_CCS_D, @@ -917,17 +918,16 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer, state, i, begin->renderArea, &clear_color); - struct isl_view view = iview->isl; - view.usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT; - view.swizzle = anv_swizzle_for_render(view.swizzle); - isl_surf_fill_state(isl_dev, - state->attachments[i].color_rt_state.map, - .surf = &iview->image->color_surface.isl, - .view = &view, - .aux_surf = &iview->image->aux_surface.isl, - .aux_usage = state->attachments[i].aux_usage, - .clear_color = clear_color, - .mocs = cmd_buffer->device->default_mocs); + anv_image_fill_surface_state(cmd_buffer->device, + iview->image, + VK_IMAGE_ASPECT_COLOR_BIT, + &iview->isl, + ISL_SURF_USAGE_RENDER_TARGET_BIT, + state->attachments[i].aux_usage, + &clear_color, + 0, + &state->attachments[i].color_rt_state, + NULL); add_image_relocs(cmd_buffer, iview->image, iview->aspect_mask, state->attachments[i].aux_usage, @@ -942,24 +942,22 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer, } if (need_input_attachment_state(&pass->attachments[i])) { - struct isl_view view = iview->isl; - view.usage |= ISL_SURF_USAGE_TEXTURE_BIT; - isl_surf_fill_state(isl_dev, - state->attachments[i].input_att_state.map, - .surf = &iview->image->color_surface.isl, - .view = &view, - .aux_surf = &iview->image->aux_surface.isl, - .aux_usage = state->attachments[i].input_aux_usage, - .clear_color = clear_color, - .mocs = cmd_buffer->device->default_mocs); + anv_image_fill_surface_state(cmd_buffer->device, + iview->image, + VK_IMAGE_ASPECT_COLOR_BIT, + &iview->isl, + ISL_SURF_USAGE_TEXTURE_BIT, + state->attachments[i].input_aux_usage, + &clear_color, + 0, + &state->attachments[i].input_att_state, + NULL); add_image_relocs(cmd_buffer, iview->image, iview->aspect_mask, state->attachments[i].input_aux_usage, state->attachments[i].input_att_state); } } - - anv_state_flush(cmd_buffer->device, state->render_pass_states); } return VK_SUCCESS; -- 2.7.4