X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fintel%2Fvulkan%2Fanv_image.c;h=e59ef4dbb6759ebe5d7786bc7b5e282e5f5bbc31;hb=b090033087d9e00740cec3abb7ff5febf13f20a7;hp=4b730aec353fc666c450f00d4eafbe0942166e97;hpb=0c403df310fef209f764acd63a544178f8020247;p=mesa.git diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index 4b730aec353..e59ef4dbb67 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -75,8 +75,11 @@ choose_isl_surf_usage(VkImageUsageFlags vk_usage, isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT; } - if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { - /* blorp implements transfers by rendering into the destination image. */ + if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT && + aspect == VK_IMAGE_ASPECT_COLOR_BIT) { + /* blorp implements transfers by rendering into the destination image. + * Only request this with color images, as we deal with depth/stencil + * formats differently. */ isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT; } @@ -176,22 +179,63 @@ make_surface(const struct anv_device *dev, /* Add a HiZ surface to a depth buffer that will be used for rendering. */ - if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT && - (image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { - + if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) { /* Allow the user to control HiZ enabling. Disable by default on gen7 * because resolves are not currently implemented pre-BDW. */ - if (!env_var_as_boolean("INTEL_VK_HIZ", dev->info.gen >= 8)) { + if (!(image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { + /* It will never be used as an attachment, HiZ is pointless. */ + } else if (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { + /* From the 1.0.37 spec: + * + * "An attachment used as an input attachment and depth/stencil + * attachment must be in either VK_IMAGE_LAYOUT_GENERAL or + * VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL." + * + * It will never have a layout of + * VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, so HiZ is + * currently pointless. If transfer operations learn to use the HiZ + * buffer, we can enable HiZ for VK_IMAGE_LAYOUT_GENERAL and support + * input attachments. + */ + anv_finishme("Implement HiZ for input attachments"); + } else if (!env_var_as_boolean("INTEL_VK_HIZ", dev->info.gen >= 8)) { anv_finishme("Implement gen7 HiZ"); } else if (vk_info->mipLevels > 1) { anv_finishme("Test multi-LOD HiZ"); + } else if (vk_info->arrayLayers > 1) { + anv_finishme("Implement multi-arrayLayer HiZ clears and resolves"); } else if (dev->info.gen == 8 && vk_info->samples > 1) { anv_finishme("Test gen8 multisampled HiZ"); } else { + assert(image->aux_surface.isl.size == 0); isl_surf_get_hiz_surf(&dev->isl_dev, &image->depth_surface.isl, - &image->hiz_surface.isl); - add_surface(image, &image->hiz_surface); + &image->aux_surface.isl); + add_surface(image, &image->aux_surface); + image->aux_usage = ISL_AUX_USAGE_HIZ; + } + } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && vk_info->samples == 1) { + if (!unlikely(INTEL_DEBUG & DEBUG_NO_RBC)) { + assert(image->aux_surface.isl.size == 0); + ok = isl_surf_get_ccs_surf(&dev->isl_dev, &anv_surf->isl, + &image->aux_surface.isl); + if (ok) { + add_surface(image, &image->aux_surface); + + /* For images created without MUTABLE_FORMAT_BIT set, we know that + * they will always be used with the original format. In + * particular, they will always be used with a format that + * supports color compression. If it's never used as a storage + * image, then it will only be used through the sampler or the as + * a render target. This means that it's safe to just leave + * compression on at all times for these formats. + */ + if (!(vk_info->usage & VK_IMAGE_USAGE_STORAGE_BIT) && + !(vk_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && + isl_format_supports_ccs_e(&dev->info, format)) { + image->aux_usage = ISL_AUX_USAGE_CCS_E; + } + } } } @@ -233,6 +277,7 @@ anv_image_create(VkDevice _device, image->samples = pCreateInfo->samples; image->usage = pCreateInfo->usage; image->tiling = pCreateInfo->tiling; + image->aux_usage = ISL_AUX_USAGE_NONE; uint32_t b; for_each_bit(b, image->aspects) { @@ -297,21 +342,23 @@ VkResult anv_BindImageMemory( image->offset = 0; } - if (anv_image_has_hiz(image)) { + if (image->aux_surface.isl.size > 0) { /* The offset and size must be a multiple of 4K or else the * anv_gem_mmap call below will return NULL. */ - assert((image->offset + image->hiz_surface.offset) % 4096 == 0); - assert(image->hiz_surface.isl.size % 4096 == 0); - - /* HiZ surfaces need to have their memory cleared to 0 before they - * can be used. If we let it have garbage data, it can cause GPU - * hangs on some hardware. + assert((image->offset + image->aux_surface.offset) % 4096 == 0); + assert(image->aux_surface.isl.size % 4096 == 0); + + /* Auxiliary surfaces need to have their memory cleared to 0 before they + * can be used. For CCS surfaces, this puts them in the "resolved" + * state so they can be used with CCS enabled before we ever touch it + * from the GPU. For HiZ, we need something valid or else we may get + * GPU hangs on some hardware and 0 works fine. */ void *map = anv_gem_mmap(device, image->bo->gem_handle, - image->offset + image->hiz_surface.offset, - image->hiz_surface.isl.size, + image->offset + image->aux_surface.offset, + image->aux_surface.isl.size, device->info.has_llc ? 0 : I915_MMAP_WC); /* If anv_gem_mmap returns NULL, it's likely that the kernel was @@ -320,9 +367,9 @@ VkResult anv_BindImageMemory( if (map == NULL) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - memset(map, 0, image->hiz_surface.isl.size); + memset(map, 0, image->aux_surface.isl.size); - anv_gem_munmap(map, image->hiz_surface.isl.size); + anv_gem_munmap(map, image->aux_surface.isl.size); } return VK_SUCCESS; @@ -475,7 +522,7 @@ anv_CreateImageView(VkDevice _device, .depth = anv_minify(image->extent.depth , range->baseMipLevel), }; - if (image->type == VK_IMAGE_TYPE_3D) { + if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) { iview->isl.base_array_layer = 0; iview->isl.array_len = iview->extent.depth; } @@ -487,7 +534,33 @@ anv_CreateImageView(VkDevice _device, iview->isl.usage = 0; } - if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT) { + /* If the HiZ buffer can be sampled from, set the constant clear color. + * If it cannot, disable the isl aux usage flag. + */ + float red_clear_color = 0.0f; + enum isl_aux_usage surf_usage = image->aux_usage; + if (image->aux_usage == ISL_AUX_USAGE_HIZ) { + if (iview->aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT && + anv_can_sample_with_hiz(device->info.gen, image->samples)) { + /* When a HiZ buffer is sampled on gen9+, ensure that + * the constant fast clear value is set in the surface state. + */ + if (device->info.gen >= 9) + red_clear_color = ANV_HZ_FC_VAL; + } else { + surf_usage = ISL_AUX_USAGE_NONE; + } + } + + /* Input attachment surfaces for color are allocated and filled + * out at BeginRenderPass time because they need compression information. + * Compression is not yet enabled for depth textures and stencil doesn't + * allow compression so we can just use the texture surface state from the + * view. + */ + if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT || + (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT && + !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) { iview->sampler_surface_state = alloc_surface_state(device); struct isl_view view = iview->isl; @@ -496,6 +569,9 @@ anv_CreateImageView(VkDevice _device, iview->sampler_surface_state.map, .surf = &surface->isl, .view = &view, + .clear_color.f32 = { red_clear_color,}, + .aux_surf = &image->aux_surface.isl, + .aux_usage = surf_usage, .mocs = device->default_mocs); if (!device->info.has_llc) @@ -518,6 +594,8 @@ anv_CreateImageView(VkDevice _device, iview->storage_surface_state.map, .surf = &surface->isl, .view = &view, + .aux_surf = &image->aux_surface.isl, + .aux_usage = surf_usage, .mocs = device->default_mocs); } else { anv_fill_buffer_surface_state(device, iview->storage_surface_state,