Path: blob/21.2-virgl/src/intel/vulkan/anv_blorp.c
4547 views
/*1* Copyright © 2016 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "anv_private.h"2425static bool26lookup_blorp_shader(struct blorp_batch *batch,27const void *key, uint32_t key_size,28uint32_t *kernel_out, void *prog_data_out)29{30struct blorp_context *blorp = batch->blorp;31struct anv_device *device = blorp->driver_ctx;3233/* The default cache must be a real cache */34assert(device->default_pipeline_cache.cache);3536struct anv_shader_bin *bin =37anv_pipeline_cache_search(&device->default_pipeline_cache, key, key_size);38if (!bin)39return false;4041/* The cache already has a reference and it's not going anywhere so there42* is no need to hold a second reference.43*/44anv_shader_bin_unref(device, bin);4546*kernel_out = bin->kernel.offset;47*(const struct brw_stage_prog_data **)prog_data_out = bin->prog_data;4849return true;50}5152static bool53upload_blorp_shader(struct blorp_batch *batch, uint32_t stage,54const void *key, uint32_t key_size,55const void *kernel, uint32_t kernel_size,56const struct brw_stage_prog_data *prog_data,57uint32_t prog_data_size,58uint32_t *kernel_out, void *prog_data_out)59{60struct blorp_context *blorp = batch->blorp;61struct anv_device *device = blorp->driver_ctx;6263/* The blorp cache must be a real cache */64assert(device->default_pipeline_cache.cache);6566struct anv_pipeline_bind_map bind_map = {67.surface_count = 0,68.sampler_count = 0,69};7071struct anv_shader_bin *bin =72anv_pipeline_cache_upload_kernel(&device->default_pipeline_cache, stage,73key, key_size, kernel, kernel_size,74prog_data, prog_data_size,75NULL, 0, NULL, &bind_map);7677if (!bin)78return false;7980/* The cache already has a reference and it's not going anywhere so there81* is no need to hold a second reference.82*/83anv_shader_bin_unref(device, bin);8485*kernel_out = bin->kernel.offset;86*(const struct brw_stage_prog_data **)prog_data_out = bin->prog_data;8788return true;89}9091void92anv_device_init_blorp(struct anv_device *device)93{94blorp_init(&device->blorp, device, &device->isl_dev);95device->blorp.compiler = device->physical->compiler;96device->blorp.lookup_shader = lookup_blorp_shader;97device->blorp.upload_shader = upload_blorp_shader;98switch (device->info.verx10) {99case 70:100device->blorp.exec = gfx7_blorp_exec;101break;102case 75:103device->blorp.exec = gfx75_blorp_exec;104break;105case 80:106device->blorp.exec = gfx8_blorp_exec;107break;108case 90:109device->blorp.exec = gfx9_blorp_exec;110break;111case 110:112device->blorp.exec = gfx11_blorp_exec;113break;114case 120:115device->blorp.exec = gfx12_blorp_exec;116break;117case 125:118device->blorp.exec = gfx125_blorp_exec;119break;120default:121unreachable("Unknown hardware generation");122}123}124125void126anv_device_finish_blorp(struct anv_device *device)127{128blorp_finish(&device->blorp);129}130131static void132get_blorp_surf_for_anv_buffer(struct anv_device *device,133struct anv_buffer *buffer, uint64_t offset,134uint32_t width, uint32_t height,135uint32_t row_pitch, enum isl_format format,136bool is_dest,137struct blorp_surf *blorp_surf,138struct isl_surf *isl_surf)139{140const struct isl_format_layout *fmtl =141isl_format_get_layout(format);142bool ok UNUSED;143144/* ASTC is the only format which doesn't support linear layouts.145* Create an equivalently sized surface with ISL to get around this.146*/147if (fmtl->txc == ISL_TXC_ASTC) {148/* Use an equivalently sized format */149format = ISL_FORMAT_R32G32B32A32_UINT;150assert(fmtl->bpb == isl_format_get_layout(format)->bpb);151152/* Shrink the dimensions for the new format */153width = DIV_ROUND_UP(width, fmtl->bw);154height = DIV_ROUND_UP(height, fmtl->bh);155}156157*blorp_surf = (struct blorp_surf) {158.surf = isl_surf,159.addr = {160.buffer = buffer->address.bo,161.offset = buffer->address.offset + offset,162.mocs = anv_mocs(device, buffer->address.bo,163is_dest ? ISL_SURF_USAGE_RENDER_TARGET_BIT164: ISL_SURF_USAGE_TEXTURE_BIT),165},166};167168ok = isl_surf_init(&device->isl_dev, isl_surf,169.dim = ISL_SURF_DIM_2D,170.format = format,171.width = width,172.height = height,173.depth = 1,174.levels = 1,175.array_len = 1,176.samples = 1,177.row_pitch_B = row_pitch,178.usage = is_dest ? ISL_SURF_USAGE_RENDER_TARGET_BIT179: ISL_SURF_USAGE_TEXTURE_BIT,180.tiling_flags = ISL_TILING_LINEAR_BIT);181assert(ok);182}183184/* Pick something high enough that it won't be used in core and low enough it185* will never map to an extension.186*/187#define ANV_IMAGE_LAYOUT_EXPLICIT_AUX (VkImageLayout)10000000188189static struct blorp_address190anv_to_blorp_address(struct anv_address addr)191{192return (struct blorp_address) {193.buffer = addr.bo,194.offset = addr.offset,195};196}197198static void199get_blorp_surf_for_anv_image(const struct anv_device *device,200const struct anv_image *image,201VkImageAspectFlags aspect,202VkImageUsageFlags usage,203VkImageLayout layout,204enum isl_aux_usage aux_usage,205struct blorp_surf *blorp_surf)206{207uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);208209if (layout != ANV_IMAGE_LAYOUT_EXPLICIT_AUX) {210assert(usage != 0);211aux_usage = anv_layout_to_aux_usage(&device->info, image,212aspect, usage, layout);213}214215isl_surf_usage_flags_t mocs_usage =216(usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) ?217ISL_SURF_USAGE_RENDER_TARGET_BIT : ISL_SURF_USAGE_TEXTURE_BIT;218219const struct anv_surface *surface = &image->planes[plane].primary_surface;220const struct anv_address address =221anv_image_address(image, &surface->memory_range);222223*blorp_surf = (struct blorp_surf) {224.surf = &surface->isl,225.addr = {226.buffer = address.bo,227.offset = address.offset,228.mocs = anv_mocs(device, address.bo, mocs_usage),229},230};231232if (aux_usage != ISL_AUX_USAGE_NONE) {233const struct anv_surface *aux_surface = &image->planes[plane].aux_surface;234const struct anv_address aux_address =235anv_image_address(image, &aux_surface->memory_range);236237blorp_surf->aux_usage = aux_usage;238blorp_surf->aux_surf = &aux_surface->isl;239240if (!anv_address_is_null(aux_address)) {241blorp_surf->aux_addr = (struct blorp_address) {242.buffer = aux_address.bo,243.offset = aux_address.offset,244.mocs = anv_mocs(device, aux_address.bo, 0),245};246}247248/* If we're doing a partial resolve, then we need the indirect clear249* color. If we are doing a fast clear and want to store/update the250* clear color, we also pass the address to blorp, otherwise it will only251* stomp the CCS to a particular value and won't care about format or252* clear value253*/254if (aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) {255const struct anv_address clear_color_addr =256anv_image_get_clear_color_addr(device, image, aspect);257blorp_surf->clear_color_addr = anv_to_blorp_address(clear_color_addr);258} else if (aspect & VK_IMAGE_ASPECT_DEPTH_BIT) {259const struct anv_address clear_color_addr =260anv_image_get_clear_color_addr(device, image, aspect);261blorp_surf->clear_color_addr = anv_to_blorp_address(clear_color_addr);262blorp_surf->clear_color = (union isl_color_value) {263.f32 = { ANV_HZ_FC_VAL },264};265}266}267}268269static bool270get_blorp_surf_for_anv_shadow_image(const struct anv_device *device,271const struct anv_image *image,272VkImageAspectFlags aspect,273struct blorp_surf *blorp_surf)274{275276uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);277if (!anv_surface_is_valid(&image->planes[plane].shadow_surface))278return false;279280const struct anv_surface *surface = &image->planes[plane].shadow_surface;281const struct anv_address address =282anv_image_address(image, &surface->memory_range);283284*blorp_surf = (struct blorp_surf) {285.surf = &surface->isl,286.addr = {287.buffer = address.bo,288.offset = address.offset,289.mocs = anv_mocs(device, address.bo, ISL_SURF_USAGE_RENDER_TARGET_BIT),290},291};292293return true;294}295296static void297copy_image(struct anv_cmd_buffer *cmd_buffer,298struct blorp_batch *batch,299struct anv_image *src_image,300VkImageLayout src_image_layout,301struct anv_image *dst_image,302VkImageLayout dst_image_layout,303const VkImageCopy2KHR *region)304{305VkOffset3D srcOffset =306anv_sanitize_image_offset(src_image->type, region->srcOffset);307VkOffset3D dstOffset =308anv_sanitize_image_offset(dst_image->type, region->dstOffset);309VkExtent3D extent =310anv_sanitize_image_extent(src_image->type, region->extent);311312const uint32_t dst_level = region->dstSubresource.mipLevel;313unsigned dst_base_layer, layer_count;314if (dst_image->type == VK_IMAGE_TYPE_3D) {315dst_base_layer = region->dstOffset.z;316layer_count = region->extent.depth;317} else {318dst_base_layer = region->dstSubresource.baseArrayLayer;319layer_count =320anv_get_layerCount(dst_image, ®ion->dstSubresource);321}322323const uint32_t src_level = region->srcSubresource.mipLevel;324unsigned src_base_layer;325if (src_image->type == VK_IMAGE_TYPE_3D) {326src_base_layer = region->srcOffset.z;327} else {328src_base_layer = region->srcSubresource.baseArrayLayer;329assert(layer_count ==330anv_get_layerCount(src_image, ®ion->srcSubresource));331}332333VkImageAspectFlags src_mask = region->srcSubresource.aspectMask,334dst_mask = region->dstSubresource.aspectMask;335336assert(anv_image_aspects_compatible(src_mask, dst_mask));337338if (util_bitcount(src_mask) > 1) {339anv_foreach_image_aspect_bit(aspect_bit, src_image, src_mask) {340struct blorp_surf src_surf, dst_surf;341get_blorp_surf_for_anv_image(cmd_buffer->device,342src_image, 1UL << aspect_bit,343VK_IMAGE_USAGE_TRANSFER_SRC_BIT,344src_image_layout, ISL_AUX_USAGE_NONE,345&src_surf);346get_blorp_surf_for_anv_image(cmd_buffer->device,347dst_image, 1UL << aspect_bit,348VK_IMAGE_USAGE_TRANSFER_DST_BIT,349dst_image_layout, ISL_AUX_USAGE_NONE,350&dst_surf);351anv_cmd_buffer_mark_image_written(cmd_buffer, dst_image,3521UL << aspect_bit,353dst_surf.aux_usage, dst_level,354dst_base_layer, layer_count);355356for (unsigned i = 0; i < layer_count; i++) {357blorp_copy(batch, &src_surf, src_level, src_base_layer + i,358&dst_surf, dst_level, dst_base_layer + i,359srcOffset.x, srcOffset.y,360dstOffset.x, dstOffset.y,361extent.width, extent.height);362}363364struct blorp_surf dst_shadow_surf;365if (get_blorp_surf_for_anv_shadow_image(cmd_buffer->device,366dst_image,3671UL << aspect_bit,368&dst_shadow_surf)) {369for (unsigned i = 0; i < layer_count; i++) {370blorp_copy(batch, &src_surf, src_level, src_base_layer + i,371&dst_shadow_surf, dst_level, dst_base_layer + i,372srcOffset.x, srcOffset.y,373dstOffset.x, dstOffset.y,374extent.width, extent.height);375}376}377}378} else {379struct blorp_surf src_surf, dst_surf;380get_blorp_surf_for_anv_image(cmd_buffer->device, src_image, src_mask,381VK_IMAGE_USAGE_TRANSFER_SRC_BIT,382src_image_layout, ISL_AUX_USAGE_NONE,383&src_surf);384get_blorp_surf_for_anv_image(cmd_buffer->device, dst_image, dst_mask,385VK_IMAGE_USAGE_TRANSFER_DST_BIT,386dst_image_layout, ISL_AUX_USAGE_NONE,387&dst_surf);388anv_cmd_buffer_mark_image_written(cmd_buffer, dst_image, dst_mask,389dst_surf.aux_usage, dst_level,390dst_base_layer, layer_count);391392for (unsigned i = 0; i < layer_count; i++) {393blorp_copy(batch, &src_surf, src_level, src_base_layer + i,394&dst_surf, dst_level, dst_base_layer + i,395srcOffset.x, srcOffset.y,396dstOffset.x, dstOffset.y,397extent.width, extent.height);398}399400struct blorp_surf dst_shadow_surf;401if (get_blorp_surf_for_anv_shadow_image(cmd_buffer->device,402dst_image, dst_mask,403&dst_shadow_surf)) {404for (unsigned i = 0; i < layer_count; i++) {405blorp_copy(batch, &src_surf, src_level, src_base_layer + i,406&dst_shadow_surf, dst_level, dst_base_layer + i,407srcOffset.x, srcOffset.y,408dstOffset.x, dstOffset.y,409extent.width, extent.height);410}411}412}413}414415void anv_CmdCopyImage2KHR(416VkCommandBuffer commandBuffer,417const VkCopyImageInfo2KHR* pCopyImageInfo)418{419ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);420ANV_FROM_HANDLE(anv_image, src_image, pCopyImageInfo->srcImage);421ANV_FROM_HANDLE(anv_image, dst_image, pCopyImageInfo->dstImage);422423struct blorp_batch batch;424blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);425426for (unsigned r = 0; r < pCopyImageInfo->regionCount; r++) {427copy_image(cmd_buffer, &batch,428src_image, pCopyImageInfo->srcImageLayout,429dst_image, pCopyImageInfo->dstImageLayout,430&pCopyImageInfo->pRegions[r]);431}432433blorp_batch_finish(&batch);434}435436static enum isl_format437isl_format_for_size(unsigned size_B)438{439/* Prefer 32-bit per component formats for CmdFillBuffer */440switch (size_B) {441case 1: return ISL_FORMAT_R8_UINT;442case 2: return ISL_FORMAT_R16_UINT;443case 3: return ISL_FORMAT_R8G8B8_UINT;444case 4: return ISL_FORMAT_R32_UINT;445case 6: return ISL_FORMAT_R16G16B16_UINT;446case 8: return ISL_FORMAT_R32G32_UINT;447case 12: return ISL_FORMAT_R32G32B32_UINT;448case 16: return ISL_FORMAT_R32G32B32A32_UINT;449default:450unreachable("Unknown format size");451}452}453454static void455copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,456struct blorp_batch *batch,457struct anv_buffer *anv_buffer,458struct anv_image *anv_image,459VkImageLayout image_layout,460const VkBufferImageCopy2KHR* region,461bool buffer_to_image)462{463struct {464struct blorp_surf surf;465uint32_t level;466VkOffset3D offset;467} image, buffer, *src, *dst;468469buffer.level = 0;470buffer.offset = (VkOffset3D) { 0, 0, 0 };471472if (buffer_to_image) {473src = &buffer;474dst = ℑ475} else {476src = ℑ477dst = &buffer;478}479480const VkImageAspectFlags aspect = region->imageSubresource.aspectMask;481482get_blorp_surf_for_anv_image(cmd_buffer->device, anv_image, aspect,483buffer_to_image ?484VK_IMAGE_USAGE_TRANSFER_DST_BIT :485VK_IMAGE_USAGE_TRANSFER_SRC_BIT,486image_layout, ISL_AUX_USAGE_NONE,487&image.surf);488image.offset =489anv_sanitize_image_offset(anv_image->type, region->imageOffset);490image.level = region->imageSubresource.mipLevel;491492VkExtent3D extent =493anv_sanitize_image_extent(anv_image->type, region->imageExtent);494if (anv_image->type != VK_IMAGE_TYPE_3D) {495image.offset.z = region->imageSubresource.baseArrayLayer;496extent.depth =497anv_get_layerCount(anv_image, ®ion->imageSubresource);498}499500const enum isl_format linear_format =501anv_get_isl_format(&cmd_buffer->device->info, anv_image->vk_format,502aspect, VK_IMAGE_TILING_LINEAR);503const struct isl_format_layout *linear_fmtl =504isl_format_get_layout(linear_format);505506const uint32_t buffer_row_length =507region->bufferRowLength ?508region->bufferRowLength : extent.width;509510const uint32_t buffer_image_height =511region->bufferImageHeight ?512region->bufferImageHeight : extent.height;513514const uint32_t buffer_row_pitch =515DIV_ROUND_UP(buffer_row_length, linear_fmtl->bw) *516(linear_fmtl->bpb / 8);517518const uint32_t buffer_layer_stride =519DIV_ROUND_UP(buffer_image_height, linear_fmtl->bh) *520buffer_row_pitch;521522/* Some formats have additional restrictions which may cause ISL to523* fail to create a surface for us. Some examples include:524*525* 1. ASTC formats are not allowed to be LINEAR and must be tiled526* 2. YCbCr formats have to have 2-pixel aligned strides527*528* To avoid these issues, we always bind the buffer as if it's a529* "normal" format like RGBA32_UINT. Since we're using blorp_copy,530* the format doesn't matter as long as it has the right bpb.531*/532const VkExtent2D buffer_extent = {533.width = DIV_ROUND_UP(extent.width, linear_fmtl->bw),534.height = DIV_ROUND_UP(extent.height, linear_fmtl->bh),535};536const enum isl_format buffer_format =537isl_format_for_size(linear_fmtl->bpb / 8);538539struct isl_surf buffer_isl_surf;540get_blorp_surf_for_anv_buffer(cmd_buffer->device,541anv_buffer, region->bufferOffset,542buffer_extent.width, buffer_extent.height,543buffer_row_pitch, buffer_format, false,544&buffer.surf, &buffer_isl_surf);545546bool dst_has_shadow = false;547struct blorp_surf dst_shadow_surf;548if (&image == dst) {549/* In this case, the source is the buffer and, since blorp takes its550* copy dimensions in terms of the source format, we have to use the551* scaled down version for compressed textures because the source552* format is an RGB format.553*/554extent.width = buffer_extent.width;555extent.height = buffer_extent.height;556557anv_cmd_buffer_mark_image_written(cmd_buffer, anv_image,558aspect, dst->surf.aux_usage,559dst->level,560dst->offset.z, extent.depth);561562dst_has_shadow =563get_blorp_surf_for_anv_shadow_image(cmd_buffer->device,564anv_image, aspect,565&dst_shadow_surf);566}567568for (unsigned z = 0; z < extent.depth; z++) {569blorp_copy(batch, &src->surf, src->level, src->offset.z,570&dst->surf, dst->level, dst->offset.z,571src->offset.x, src->offset.y, dst->offset.x, dst->offset.y,572extent.width, extent.height);573574if (dst_has_shadow) {575blorp_copy(batch, &src->surf, src->level, src->offset.z,576&dst_shadow_surf, dst->level, dst->offset.z,577src->offset.x, src->offset.y,578dst->offset.x, dst->offset.y,579extent.width, extent.height);580}581582image.offset.z++;583buffer.surf.addr.offset += buffer_layer_stride;584}585}586587void anv_CmdCopyBufferToImage2KHR(588VkCommandBuffer commandBuffer,589const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo)590{591ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);592ANV_FROM_HANDLE(anv_buffer, src_buffer, pCopyBufferToImageInfo->srcBuffer);593ANV_FROM_HANDLE(anv_image, dst_image, pCopyBufferToImageInfo->dstImage);594595struct blorp_batch batch;596blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);597598for (unsigned r = 0; r < pCopyBufferToImageInfo->regionCount; r++) {599copy_buffer_to_image(cmd_buffer, &batch, src_buffer, dst_image,600pCopyBufferToImageInfo->dstImageLayout,601&pCopyBufferToImageInfo->pRegions[r], true);602}603604blorp_batch_finish(&batch);605}606607void anv_CmdCopyImageToBuffer2KHR(608VkCommandBuffer commandBuffer,609const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo)610{611ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);612ANV_FROM_HANDLE(anv_image, src_image, pCopyImageToBufferInfo->srcImage);613ANV_FROM_HANDLE(anv_buffer, dst_buffer, pCopyImageToBufferInfo->dstBuffer);614615struct blorp_batch batch;616blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);617618for (unsigned r = 0; r < pCopyImageToBufferInfo->regionCount; r++) {619copy_buffer_to_image(cmd_buffer, &batch, dst_buffer, src_image,620pCopyImageToBufferInfo->srcImageLayout,621&pCopyImageToBufferInfo->pRegions[r], false);622}623624blorp_batch_finish(&batch);625626cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_BUFFER_WRITES;627}628629static bool630flip_coords(unsigned *src0, unsigned *src1, unsigned *dst0, unsigned *dst1)631{632bool flip = false;633if (*src0 > *src1) {634unsigned tmp = *src0;635*src0 = *src1;636*src1 = tmp;637flip = !flip;638}639640if (*dst0 > *dst1) {641unsigned tmp = *dst0;642*dst0 = *dst1;643*dst1 = tmp;644flip = !flip;645}646647return flip;648}649650static void651blit_image(struct anv_cmd_buffer *cmd_buffer,652struct blorp_batch *batch,653struct anv_image *src_image,654VkImageLayout src_image_layout,655struct anv_image *dst_image,656VkImageLayout dst_image_layout,657const VkImageBlit2KHR *region,658VkFilter filter)659{660const VkImageSubresourceLayers *src_res = ®ion->srcSubresource;661const VkImageSubresourceLayers *dst_res = ®ion->dstSubresource;662663struct blorp_surf src, dst;664665enum blorp_filter blorp_filter;666switch (filter) {667case VK_FILTER_NEAREST:668blorp_filter = BLORP_FILTER_NEAREST;669break;670case VK_FILTER_LINEAR:671blorp_filter = BLORP_FILTER_BILINEAR;672break;673default:674unreachable("Invalid filter");675}676677assert(anv_image_aspects_compatible(src_res->aspectMask,678dst_res->aspectMask));679680anv_foreach_image_aspect_bit(aspect_bit, src_image, src_res->aspectMask) {681get_blorp_surf_for_anv_image(cmd_buffer->device,682src_image, 1U << aspect_bit,683VK_IMAGE_USAGE_TRANSFER_SRC_BIT,684src_image_layout, ISL_AUX_USAGE_NONE, &src);685get_blorp_surf_for_anv_image(cmd_buffer->device,686dst_image, 1U << aspect_bit,687VK_IMAGE_USAGE_TRANSFER_DST_BIT,688dst_image_layout, ISL_AUX_USAGE_NONE, &dst);689690struct anv_format_plane src_format =691anv_get_format_plane(&cmd_buffer->device->info, src_image->vk_format,6921U << aspect_bit, src_image->tiling);693struct anv_format_plane dst_format =694anv_get_format_plane(&cmd_buffer->device->info, dst_image->vk_format,6951U << aspect_bit, dst_image->tiling);696697unsigned dst_start, dst_end;698if (dst_image->type == VK_IMAGE_TYPE_3D) {699assert(dst_res->baseArrayLayer == 0);700dst_start = region->dstOffsets[0].z;701dst_end = region->dstOffsets[1].z;702} else {703dst_start = dst_res->baseArrayLayer;704dst_end = dst_start + anv_get_layerCount(dst_image, dst_res);705}706707unsigned src_start, src_end;708if (src_image->type == VK_IMAGE_TYPE_3D) {709assert(src_res->baseArrayLayer == 0);710src_start = region->srcOffsets[0].z;711src_end = region->srcOffsets[1].z;712} else {713src_start = src_res->baseArrayLayer;714src_end = src_start + anv_get_layerCount(src_image, src_res);715}716717bool flip_z = flip_coords(&src_start, &src_end, &dst_start, &dst_end);718const unsigned num_layers = dst_end - dst_start;719float src_z_step = (float)(src_end - src_start) / (float)num_layers;720721/* There is no interpolation to the pixel center during rendering, so722* add the 0.5 offset ourselves here. */723float depth_center_offset = 0;724if (src_image->type == VK_IMAGE_TYPE_3D)725depth_center_offset = 0.5 / num_layers * (src_end - src_start);726727if (flip_z) {728src_start = src_end;729src_z_step *= -1;730depth_center_offset *= -1;731}732733unsigned src_x0 = region->srcOffsets[0].x;734unsigned src_x1 = region->srcOffsets[1].x;735unsigned dst_x0 = region->dstOffsets[0].x;736unsigned dst_x1 = region->dstOffsets[1].x;737bool flip_x = flip_coords(&src_x0, &src_x1, &dst_x0, &dst_x1);738739unsigned src_y0 = region->srcOffsets[0].y;740unsigned src_y1 = region->srcOffsets[1].y;741unsigned dst_y0 = region->dstOffsets[0].y;742unsigned dst_y1 = region->dstOffsets[1].y;743bool flip_y = flip_coords(&src_y0, &src_y1, &dst_y0, &dst_y1);744745anv_cmd_buffer_mark_image_written(cmd_buffer, dst_image,7461U << aspect_bit,747dst.aux_usage,748dst_res->mipLevel,749dst_start, num_layers);750751for (unsigned i = 0; i < num_layers; i++) {752unsigned dst_z = dst_start + i;753float src_z = src_start + i * src_z_step + depth_center_offset;754755blorp_blit(batch, &src, src_res->mipLevel, src_z,756src_format.isl_format, src_format.swizzle,757&dst, dst_res->mipLevel, dst_z,758dst_format.isl_format, dst_format.swizzle,759src_x0, src_y0, src_x1, src_y1,760dst_x0, dst_y0, dst_x1, dst_y1,761blorp_filter, flip_x, flip_y);762}763}764}765766void anv_CmdBlitImage2KHR(767VkCommandBuffer commandBuffer,768const VkBlitImageInfo2KHR* pBlitImageInfo)769{770ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);771ANV_FROM_HANDLE(anv_image, src_image, pBlitImageInfo->srcImage);772ANV_FROM_HANDLE(anv_image, dst_image, pBlitImageInfo->dstImage);773774struct blorp_batch batch;775blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);776777for (unsigned r = 0; r < pBlitImageInfo->regionCount; r++) {778blit_image(cmd_buffer, &batch,779src_image, pBlitImageInfo->srcImageLayout,780dst_image, pBlitImageInfo->dstImageLayout,781&pBlitImageInfo->pRegions[r], pBlitImageInfo->filter);782}783784blorp_batch_finish(&batch);785}786787/**788* Returns the greatest common divisor of a and b that is a power of two.789*/790static uint64_t791gcd_pow2_u64(uint64_t a, uint64_t b)792{793assert(a > 0 || b > 0);794795unsigned a_log2 = ffsll(a) - 1;796unsigned b_log2 = ffsll(b) - 1;797798/* If either a or b is 0, then a_log2 or b_log2 till be UINT_MAX in which799* case, the MIN2() will take the other one. If both are 0 then we will800* hit the assert above.801*/802return 1 << MIN2(a_log2, b_log2);803}804805/* This is maximum possible width/height our HW can handle */806#define MAX_SURFACE_DIM (1ull << 14)807808static void809copy_buffer(struct anv_device *device,810struct blorp_batch *batch,811struct anv_buffer *src_buffer,812struct anv_buffer *dst_buffer,813const VkBufferCopy2KHR *region)814{815struct blorp_address src = {816.buffer = src_buffer->address.bo,817.offset = src_buffer->address.offset + region->srcOffset,818.mocs = anv_mocs(device, src_buffer->address.bo,819ISL_SURF_USAGE_TEXTURE_BIT),820};821struct blorp_address dst = {822.buffer = dst_buffer->address.bo,823.offset = dst_buffer->address.offset + region->dstOffset,824.mocs = anv_mocs(device, dst_buffer->address.bo,825ISL_SURF_USAGE_RENDER_TARGET_BIT),826};827828blorp_buffer_copy(batch, src, dst, region->size);829}830831void anv_CmdCopyBuffer2KHR(832VkCommandBuffer commandBuffer,833const VkCopyBufferInfo2KHR* pCopyBufferInfo)834{835ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);836ANV_FROM_HANDLE(anv_buffer, src_buffer, pCopyBufferInfo->srcBuffer);837ANV_FROM_HANDLE(anv_buffer, dst_buffer, pCopyBufferInfo->dstBuffer);838839struct blorp_batch batch;840blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);841842for (unsigned r = 0; r < pCopyBufferInfo->regionCount; r++) {843copy_buffer(cmd_buffer->device, &batch, src_buffer, dst_buffer,844&pCopyBufferInfo->pRegions[r]);845}846847blorp_batch_finish(&batch);848849cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_BUFFER_WRITES;850}851852853void anv_CmdUpdateBuffer(854VkCommandBuffer commandBuffer,855VkBuffer dstBuffer,856VkDeviceSize dstOffset,857VkDeviceSize dataSize,858const void* pData)859{860ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);861ANV_FROM_HANDLE(anv_buffer, dst_buffer, dstBuffer);862863struct blorp_batch batch;864blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);865866/* We can't quite grab a full block because the state stream needs a867* little data at the top to build its linked list.868*/869const uint32_t max_update_size =870cmd_buffer->device->dynamic_state_pool.block_size - 64;871872assert(max_update_size < MAX_SURFACE_DIM * 4);873874/* We're about to read data that was written from the CPU. Flush the875* texture cache so we don't get anything stale.876*/877anv_add_pending_pipe_bits(cmd_buffer,878ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT,879"before UpdateBuffer");880881while (dataSize) {882const uint32_t copy_size = MIN2(dataSize, max_update_size);883884struct anv_state tmp_data =885anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, copy_size, 64);886887memcpy(tmp_data.map, pData, copy_size);888889struct blorp_address src = {890.buffer = cmd_buffer->device->dynamic_state_pool.block_pool.bo,891.offset = tmp_data.offset,892.mocs = isl_mocs(&cmd_buffer->device->isl_dev,893ISL_SURF_USAGE_TEXTURE_BIT, false)894};895struct blorp_address dst = {896.buffer = dst_buffer->address.bo,897.offset = dst_buffer->address.offset + dstOffset,898.mocs = anv_mocs(cmd_buffer->device, dst_buffer->address.bo,899ISL_SURF_USAGE_RENDER_TARGET_BIT),900};901902blorp_buffer_copy(&batch, src, dst, copy_size);903904dataSize -= copy_size;905dstOffset += copy_size;906pData = (void *)pData + copy_size;907}908909blorp_batch_finish(&batch);910911cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_BUFFER_WRITES;912}913914void anv_CmdFillBuffer(915VkCommandBuffer commandBuffer,916VkBuffer dstBuffer,917VkDeviceSize dstOffset,918VkDeviceSize fillSize,919uint32_t data)920{921ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);922ANV_FROM_HANDLE(anv_buffer, dst_buffer, dstBuffer);923struct blorp_surf surf;924struct isl_surf isl_surf;925926struct blorp_batch batch;927blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);928929fillSize = anv_buffer_get_range(dst_buffer, dstOffset, fillSize);930931/* From the Vulkan spec:932*933* "size is the number of bytes to fill, and must be either a multiple934* of 4, or VK_WHOLE_SIZE to fill the range from offset to the end of935* the buffer. If VK_WHOLE_SIZE is used and the remaining size of the936* buffer is not a multiple of 4, then the nearest smaller multiple is937* used."938*/939fillSize &= ~3ull;940941/* First, we compute the biggest format that can be used with the942* given offsets and size.943*/944int bs = 16;945bs = gcd_pow2_u64(bs, dstOffset);946bs = gcd_pow2_u64(bs, fillSize);947enum isl_format isl_format = isl_format_for_size(bs);948949union isl_color_value color = {950.u32 = { data, data, data, data },951};952953const uint64_t max_fill_size = MAX_SURFACE_DIM * MAX_SURFACE_DIM * bs;954while (fillSize >= max_fill_size) {955get_blorp_surf_for_anv_buffer(cmd_buffer->device,956dst_buffer, dstOffset,957MAX_SURFACE_DIM, MAX_SURFACE_DIM,958MAX_SURFACE_DIM * bs, isl_format, true,959&surf, &isl_surf);960961blorp_clear(&batch, &surf, isl_format, ISL_SWIZZLE_IDENTITY,9620, 0, 1, 0, 0, MAX_SURFACE_DIM, MAX_SURFACE_DIM,963color, NULL);964fillSize -= max_fill_size;965dstOffset += max_fill_size;966}967968uint64_t height = fillSize / (MAX_SURFACE_DIM * bs);969assert(height < MAX_SURFACE_DIM);970if (height != 0) {971const uint64_t rect_fill_size = height * MAX_SURFACE_DIM * bs;972get_blorp_surf_for_anv_buffer(cmd_buffer->device,973dst_buffer, dstOffset,974MAX_SURFACE_DIM, height,975MAX_SURFACE_DIM * bs, isl_format, true,976&surf, &isl_surf);977978blorp_clear(&batch, &surf, isl_format, ISL_SWIZZLE_IDENTITY,9790, 0, 1, 0, 0, MAX_SURFACE_DIM, height,980color, NULL);981fillSize -= rect_fill_size;982dstOffset += rect_fill_size;983}984985if (fillSize != 0) {986const uint32_t width = fillSize / bs;987get_blorp_surf_for_anv_buffer(cmd_buffer->device,988dst_buffer, dstOffset,989width, 1,990width * bs, isl_format, true,991&surf, &isl_surf);992993blorp_clear(&batch, &surf, isl_format, ISL_SWIZZLE_IDENTITY,9940, 0, 1, 0, 0, width, 1,995color, NULL);996}997998blorp_batch_finish(&batch);9991000cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_BUFFER_WRITES;1001}10021003void anv_CmdClearColorImage(1004VkCommandBuffer commandBuffer,1005VkImage _image,1006VkImageLayout imageLayout,1007const VkClearColorValue* pColor,1008uint32_t rangeCount,1009const VkImageSubresourceRange* pRanges)1010{1011ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);1012ANV_FROM_HANDLE(anv_image, image, _image);10131014static const bool color_write_disable[4] = { false, false, false, false };10151016struct blorp_batch batch;1017blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);101810191020for (unsigned r = 0; r < rangeCount; r++) {1021if (pRanges[r].aspectMask == 0)1022continue;10231024assert(pRanges[r].aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);10251026struct blorp_surf surf;1027get_blorp_surf_for_anv_image(cmd_buffer->device,1028image, pRanges[r].aspectMask,1029VK_IMAGE_USAGE_TRANSFER_DST_BIT,1030imageLayout, ISL_AUX_USAGE_NONE, &surf);10311032struct anv_format_plane src_format =1033anv_get_format_plane(&cmd_buffer->device->info, image->vk_format,1034VK_IMAGE_ASPECT_COLOR_BIT, image->tiling);10351036unsigned base_layer = pRanges[r].baseArrayLayer;1037unsigned layer_count = anv_get_layerCount(image, &pRanges[r]);10381039for (unsigned i = 0; i < anv_get_levelCount(image, &pRanges[r]); i++) {1040const unsigned level = pRanges[r].baseMipLevel + i;1041const unsigned level_width = anv_minify(image->extent.width, level);1042const unsigned level_height = anv_minify(image->extent.height, level);10431044if (image->type == VK_IMAGE_TYPE_3D) {1045base_layer = 0;1046layer_count = anv_minify(image->extent.depth, level);1047}10481049anv_cmd_buffer_mark_image_written(cmd_buffer, image,1050pRanges[r].aspectMask,1051surf.aux_usage, level,1052base_layer, layer_count);10531054blorp_clear(&batch, &surf,1055src_format.isl_format, src_format.swizzle,1056level, base_layer, layer_count,10570, 0, level_width, level_height,1058vk_to_isl_color(*pColor), color_write_disable);1059}1060}10611062blorp_batch_finish(&batch);1063}10641065void anv_CmdClearDepthStencilImage(1066VkCommandBuffer commandBuffer,1067VkImage image_h,1068VkImageLayout imageLayout,1069const VkClearDepthStencilValue* pDepthStencil,1070uint32_t rangeCount,1071const VkImageSubresourceRange* pRanges)1072{1073ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);1074ANV_FROM_HANDLE(anv_image, image, image_h);10751076struct blorp_batch batch;1077blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);10781079struct blorp_surf depth, stencil, stencil_shadow;1080if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {1081get_blorp_surf_for_anv_image(cmd_buffer->device,1082image, VK_IMAGE_ASPECT_DEPTH_BIT,1083VK_IMAGE_USAGE_TRANSFER_DST_BIT,1084imageLayout, ISL_AUX_USAGE_NONE, &depth);1085} else {1086memset(&depth, 0, sizeof(depth));1087}10881089bool has_stencil_shadow = false;1090if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {1091get_blorp_surf_for_anv_image(cmd_buffer->device,1092image, VK_IMAGE_ASPECT_STENCIL_BIT,1093VK_IMAGE_USAGE_TRANSFER_DST_BIT,1094imageLayout, ISL_AUX_USAGE_NONE, &stencil);10951096has_stencil_shadow =1097get_blorp_surf_for_anv_shadow_image(cmd_buffer->device, image,1098VK_IMAGE_ASPECT_STENCIL_BIT,1099&stencil_shadow);1100} else {1101memset(&stencil, 0, sizeof(stencil));1102}11031104for (unsigned r = 0; r < rangeCount; r++) {1105if (pRanges[r].aspectMask == 0)1106continue;11071108bool clear_depth = pRanges[r].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT;1109bool clear_stencil = pRanges[r].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT;11101111unsigned base_layer = pRanges[r].baseArrayLayer;1112unsigned layer_count = anv_get_layerCount(image, &pRanges[r]);11131114for (unsigned i = 0; i < anv_get_levelCount(image, &pRanges[r]); i++) {1115const unsigned level = pRanges[r].baseMipLevel + i;1116const unsigned level_width = anv_minify(image->extent.width, level);1117const unsigned level_height = anv_minify(image->extent.height, level);11181119if (image->type == VK_IMAGE_TYPE_3D)1120layer_count = anv_minify(image->extent.depth, level);11211122blorp_clear_depth_stencil(&batch, &depth, &stencil,1123level, base_layer, layer_count,11240, 0, level_width, level_height,1125clear_depth, pDepthStencil->depth,1126clear_stencil ? 0xff : 0,1127pDepthStencil->stencil);11281129if (clear_stencil && has_stencil_shadow) {1130union isl_color_value stencil_color = {1131.u32 = { pDepthStencil->stencil, },1132};1133blorp_clear(&batch, &stencil_shadow,1134ISL_FORMAT_R8_UINT, ISL_SWIZZLE_IDENTITY,1135level, base_layer, layer_count,11360, 0, level_width, level_height,1137stencil_color, NULL);1138}1139}1140}11411142blorp_batch_finish(&batch);1143}11441145VkResult1146anv_cmd_buffer_alloc_blorp_binding_table(struct anv_cmd_buffer *cmd_buffer,1147uint32_t num_entries,1148uint32_t *state_offset,1149struct anv_state *bt_state)1150{1151*bt_state = anv_cmd_buffer_alloc_binding_table(cmd_buffer, num_entries,1152state_offset);1153if (bt_state->map == NULL) {1154/* We ran out of space. Grab a new binding table block. */1155VkResult result = anv_cmd_buffer_new_binding_table_block(cmd_buffer);1156if (result != VK_SUCCESS)1157return result;11581159/* Re-emit state base addresses so we get the new surface state base1160* address before we start emitting binding tables etc.1161*/1162anv_cmd_buffer_emit_state_base_address(cmd_buffer);11631164*bt_state = anv_cmd_buffer_alloc_binding_table(cmd_buffer, num_entries,1165state_offset);1166assert(bt_state->map != NULL);1167}11681169return VK_SUCCESS;1170}11711172static VkResult1173binding_table_for_surface_state(struct anv_cmd_buffer *cmd_buffer,1174struct anv_state surface_state,1175uint32_t *bt_offset)1176{1177uint32_t state_offset;1178struct anv_state bt_state;11791180VkResult result =1181anv_cmd_buffer_alloc_blorp_binding_table(cmd_buffer, 1, &state_offset,1182&bt_state);1183if (result != VK_SUCCESS)1184return result;11851186uint32_t *bt_map = bt_state.map;1187bt_map[0] = surface_state.offset + state_offset;11881189*bt_offset = bt_state.offset;1190return VK_SUCCESS;1191}11921193static void1194clear_color_attachment(struct anv_cmd_buffer *cmd_buffer,1195struct blorp_batch *batch,1196const VkClearAttachment *attachment,1197uint32_t rectCount, const VkClearRect *pRects)1198{1199const struct anv_subpass *subpass = cmd_buffer->state.subpass;1200const uint32_t color_att = attachment->colorAttachment;1201assert(color_att < subpass->color_count);1202const uint32_t att_idx = subpass->color_attachments[color_att].attachment;12031204if (att_idx == VK_ATTACHMENT_UNUSED)1205return;12061207struct anv_render_pass_attachment *pass_att =1208&cmd_buffer->state.pass->attachments[att_idx];1209struct anv_attachment_state *att_state =1210&cmd_buffer->state.attachments[att_idx];12111212uint32_t binding_table;1213VkResult result =1214binding_table_for_surface_state(cmd_buffer, att_state->color.state,1215&binding_table);1216if (result != VK_SUCCESS)1217return;12181219union isl_color_value clear_color =1220vk_to_isl_color(attachment->clearValue.color);12211222/* If multiview is enabled we ignore baseArrayLayer and layerCount */1223if (subpass->view_mask) {1224u_foreach_bit(view_idx, subpass->view_mask) {1225for (uint32_t r = 0; r < rectCount; ++r) {1226const VkOffset2D offset = pRects[r].rect.offset;1227const VkExtent2D extent = pRects[r].rect.extent;1228blorp_clear_attachments(batch, binding_table,1229ISL_FORMAT_UNSUPPORTED, pass_att->samples,1230view_idx, 1,1231offset.x, offset.y,1232offset.x + extent.width,1233offset.y + extent.height,1234true, clear_color, false, 0.0f, 0, 0);1235}1236}1237return;1238}12391240for (uint32_t r = 0; r < rectCount; ++r) {1241const VkOffset2D offset = pRects[r].rect.offset;1242const VkExtent2D extent = pRects[r].rect.extent;1243assert(pRects[r].layerCount != VK_REMAINING_ARRAY_LAYERS);1244blorp_clear_attachments(batch, binding_table,1245ISL_FORMAT_UNSUPPORTED, pass_att->samples,1246pRects[r].baseArrayLayer,1247pRects[r].layerCount,1248offset.x, offset.y,1249offset.x + extent.width, offset.y + extent.height,1250true, clear_color, false, 0.0f, 0, 0);1251}1252}12531254static void1255clear_depth_stencil_attachment(struct anv_cmd_buffer *cmd_buffer,1256struct blorp_batch *batch,1257const VkClearAttachment *attachment,1258uint32_t rectCount, const VkClearRect *pRects)1259{1260static const union isl_color_value color_value = { .u32 = { 0, } };1261const struct anv_subpass *subpass = cmd_buffer->state.subpass;1262if (!subpass->depth_stencil_attachment)1263return;12641265const uint32_t att_idx = subpass->depth_stencil_attachment->attachment;1266assert(att_idx != VK_ATTACHMENT_UNUSED);1267struct anv_render_pass_attachment *pass_att =1268&cmd_buffer->state.pass->attachments[att_idx];12691270bool clear_depth = attachment->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT;1271bool clear_stencil = attachment->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT;12721273enum isl_format depth_format = ISL_FORMAT_UNSUPPORTED;1274if (clear_depth) {1275depth_format = anv_get_isl_format(&cmd_buffer->device->info,1276pass_att->format,1277VK_IMAGE_ASPECT_DEPTH_BIT,1278VK_IMAGE_TILING_OPTIMAL);1279}12801281uint32_t binding_table;1282VkResult result =1283binding_table_for_surface_state(cmd_buffer,1284cmd_buffer->state.null_surface_state,1285&binding_table);1286if (result != VK_SUCCESS)1287return;12881289/* If multiview is enabled we ignore baseArrayLayer and layerCount */1290if (subpass->view_mask) {1291u_foreach_bit(view_idx, subpass->view_mask) {1292for (uint32_t r = 0; r < rectCount; ++r) {1293const VkOffset2D offset = pRects[r].rect.offset;1294const VkExtent2D extent = pRects[r].rect.extent;1295VkClearDepthStencilValue value = attachment->clearValue.depthStencil;1296blorp_clear_attachments(batch, binding_table,1297depth_format, pass_att->samples,1298view_idx, 1,1299offset.x, offset.y,1300offset.x + extent.width,1301offset.y + extent.height,1302false, color_value,1303clear_depth, value.depth,1304clear_stencil ? 0xff : 0, value.stencil);1305}1306}1307return;1308}13091310for (uint32_t r = 0; r < rectCount; ++r) {1311const VkOffset2D offset = pRects[r].rect.offset;1312const VkExtent2D extent = pRects[r].rect.extent;1313VkClearDepthStencilValue value = attachment->clearValue.depthStencil;1314assert(pRects[r].layerCount != VK_REMAINING_ARRAY_LAYERS);1315blorp_clear_attachments(batch, binding_table,1316depth_format, pass_att->samples,1317pRects[r].baseArrayLayer,1318pRects[r].layerCount,1319offset.x, offset.y,1320offset.x + extent.width, offset.y + extent.height,1321false, color_value,1322clear_depth, value.depth,1323clear_stencil ? 0xff : 0, value.stencil);1324}1325}13261327void anv_CmdClearAttachments(1328VkCommandBuffer commandBuffer,1329uint32_t attachmentCount,1330const VkClearAttachment* pAttachments,1331uint32_t rectCount,1332const VkClearRect* pRects)1333{1334ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);13351336/* Because this gets called within a render pass, we tell blorp not to1337* trash our depth and stencil buffers.1338*/1339struct blorp_batch batch;1340enum blorp_batch_flags flags = BLORP_BATCH_NO_EMIT_DEPTH_STENCIL;1341if (cmd_buffer->state.conditional_render_enabled) {1342anv_cmd_emit_conditional_render_predicate(cmd_buffer);1343flags |= BLORP_BATCH_PREDICATE_ENABLE;1344}1345blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, flags);13461347for (uint32_t a = 0; a < attachmentCount; ++a) {1348if (pAttachments[a].aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) {1349assert(pAttachments[a].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);1350clear_color_attachment(cmd_buffer, &batch,1351&pAttachments[a],1352rectCount, pRects);1353} else {1354clear_depth_stencil_attachment(cmd_buffer, &batch,1355&pAttachments[a],1356rectCount, pRects);1357}1358}13591360blorp_batch_finish(&batch);1361}13621363enum subpass_stage {1364SUBPASS_STAGE_LOAD,1365SUBPASS_STAGE_DRAW,1366SUBPASS_STAGE_RESOLVE,1367};13681369void1370anv_image_msaa_resolve(struct anv_cmd_buffer *cmd_buffer,1371const struct anv_image *src_image,1372enum isl_aux_usage src_aux_usage,1373uint32_t src_level, uint32_t src_base_layer,1374const struct anv_image *dst_image,1375enum isl_aux_usage dst_aux_usage,1376uint32_t dst_level, uint32_t dst_base_layer,1377VkImageAspectFlagBits aspect,1378uint32_t src_x, uint32_t src_y,1379uint32_t dst_x, uint32_t dst_y,1380uint32_t width, uint32_t height,1381uint32_t layer_count,1382enum blorp_filter filter)1383{1384struct blorp_batch batch;1385blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);13861387assert(src_image->type == VK_IMAGE_TYPE_2D);1388assert(src_image->samples > 1);1389assert(dst_image->type == VK_IMAGE_TYPE_2D);1390assert(dst_image->samples == 1);1391assert(src_image->n_planes == dst_image->n_planes);1392assert(!src_image->format->can_ycbcr);1393assert(!dst_image->format->can_ycbcr);13941395struct blorp_surf src_surf, dst_surf;1396get_blorp_surf_for_anv_image(cmd_buffer->device, src_image, aspect,1397VK_IMAGE_USAGE_TRANSFER_SRC_BIT,1398ANV_IMAGE_LAYOUT_EXPLICIT_AUX,1399src_aux_usage, &src_surf);1400if (src_aux_usage == ISL_AUX_USAGE_MCS) {1401src_surf.clear_color_addr = anv_to_blorp_address(1402anv_image_get_clear_color_addr(cmd_buffer->device, src_image,1403VK_IMAGE_ASPECT_COLOR_BIT));1404}1405get_blorp_surf_for_anv_image(cmd_buffer->device, dst_image, aspect,1406VK_IMAGE_USAGE_TRANSFER_DST_BIT,1407ANV_IMAGE_LAYOUT_EXPLICIT_AUX,1408dst_aux_usage, &dst_surf);1409anv_cmd_buffer_mark_image_written(cmd_buffer, dst_image,1410aspect, dst_aux_usage,1411dst_level, dst_base_layer, layer_count);14121413if (filter == BLORP_FILTER_NONE) {1414/* If no explicit filter is provided, then it's implied by the type of1415* the source image.1416*/1417if ((src_surf.surf->usage & ISL_SURF_USAGE_DEPTH_BIT) ||1418(src_surf.surf->usage & ISL_SURF_USAGE_STENCIL_BIT) ||1419isl_format_has_int_channel(src_surf.surf->format)) {1420filter = BLORP_FILTER_SAMPLE_0;1421} else {1422filter = BLORP_FILTER_AVERAGE;1423}1424}14251426for (uint32_t l = 0; l < layer_count; l++) {1427blorp_blit(&batch,1428&src_surf, src_level, src_base_layer + l,1429ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,1430&dst_surf, dst_level, dst_base_layer + l,1431ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,1432src_x, src_y, src_x + width, src_y + height,1433dst_x, dst_y, dst_x + width, dst_y + height,1434filter, false, false);1435}14361437blorp_batch_finish(&batch);1438}14391440static void1441resolve_image(struct anv_cmd_buffer *cmd_buffer,1442struct anv_image *src_image,1443VkImageLayout src_image_layout,1444struct anv_image *dst_image,1445VkImageLayout dst_image_layout,1446const VkImageResolve2KHR *region)1447{1448assert(region->srcSubresource.aspectMask == region->dstSubresource.aspectMask);1449assert(anv_get_layerCount(src_image, ®ion->srcSubresource) ==1450anv_get_layerCount(dst_image, ®ion->dstSubresource));14511452const uint32_t layer_count =1453anv_get_layerCount(dst_image, ®ion->dstSubresource);14541455anv_foreach_image_aspect_bit(aspect_bit, src_image,1456region->srcSubresource.aspectMask) {1457enum isl_aux_usage src_aux_usage =1458anv_layout_to_aux_usage(&cmd_buffer->device->info, src_image,1459(1 << aspect_bit),1460VK_IMAGE_USAGE_TRANSFER_SRC_BIT,1461src_image_layout);1462enum isl_aux_usage dst_aux_usage =1463anv_layout_to_aux_usage(&cmd_buffer->device->info, dst_image,1464(1 << aspect_bit),1465VK_IMAGE_USAGE_TRANSFER_DST_BIT,1466dst_image_layout);14671468anv_image_msaa_resolve(cmd_buffer,1469src_image, src_aux_usage,1470region->srcSubresource.mipLevel,1471region->srcSubresource.baseArrayLayer,1472dst_image, dst_aux_usage,1473region->dstSubresource.mipLevel,1474region->dstSubresource.baseArrayLayer,1475(1 << aspect_bit),1476region->srcOffset.x,1477region->srcOffset.y,1478region->dstOffset.x,1479region->dstOffset.y,1480region->extent.width,1481region->extent.height,1482layer_count, BLORP_FILTER_NONE);1483}1484}14851486void anv_CmdResolveImage2KHR(1487VkCommandBuffer commandBuffer,1488const VkResolveImageInfo2KHR* pResolveImageInfo)1489{1490ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);1491ANV_FROM_HANDLE(anv_image, src_image, pResolveImageInfo->srcImage);1492ANV_FROM_HANDLE(anv_image, dst_image, pResolveImageInfo->dstImage);14931494assert(!src_image->format->can_ycbcr);14951496for (uint32_t r = 0; r < pResolveImageInfo->regionCount; r++) {1497resolve_image(cmd_buffer,1498src_image, pResolveImageInfo->srcImageLayout,1499dst_image, pResolveImageInfo->dstImageLayout,1500&pResolveImageInfo->pRegions[r]);1501}1502}15031504void1505anv_image_copy_to_shadow(struct anv_cmd_buffer *cmd_buffer,1506const struct anv_image *image,1507VkImageAspectFlagBits aspect,1508uint32_t base_level, uint32_t level_count,1509uint32_t base_layer, uint32_t layer_count)1510{1511struct blorp_batch batch;1512blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);15131514/* We don't know who touched the main surface last so flush a bunch of1515* caches to ensure we get good data.1516*/1517anv_add_pending_pipe_bits(cmd_buffer,1518ANV_PIPE_DEPTH_CACHE_FLUSH_BIT |1519ANV_PIPE_HDC_PIPELINE_FLUSH_BIT |1520ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |1521ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT,1522"before copy_to_shadow");15231524struct blorp_surf surf;1525get_blorp_surf_for_anv_image(cmd_buffer->device,1526image, aspect,1527VK_IMAGE_USAGE_TRANSFER_SRC_BIT,1528VK_IMAGE_LAYOUT_GENERAL,1529ISL_AUX_USAGE_NONE, &surf);1530assert(surf.aux_usage == ISL_AUX_USAGE_NONE);15311532struct blorp_surf shadow_surf;1533get_blorp_surf_for_anv_shadow_image(cmd_buffer->device,1534image, aspect, &shadow_surf);15351536for (uint32_t l = 0; l < level_count; l++) {1537const uint32_t level = base_level + l;15381539const VkExtent3D extent = {1540.width = anv_minify(image->extent.width, level),1541.height = anv_minify(image->extent.height, level),1542.depth = anv_minify(image->extent.depth, level),1543};15441545if (image->type == VK_IMAGE_TYPE_3D)1546layer_count = extent.depth;15471548for (uint32_t a = 0; a < layer_count; a++) {1549const uint32_t layer = base_layer + a;15501551blorp_copy(&batch, &surf, level, layer,1552&shadow_surf, level, layer,15530, 0, 0, 0, extent.width, extent.height);1554}1555}15561557/* We just wrote to the buffer with the render cache. Flush it. */1558anv_add_pending_pipe_bits(cmd_buffer,1559ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT,1560"after copy_to_shadow");15611562blorp_batch_finish(&batch);1563}15641565void1566anv_image_clear_color(struct anv_cmd_buffer *cmd_buffer,1567const struct anv_image *image,1568VkImageAspectFlagBits aspect,1569enum isl_aux_usage aux_usage,1570enum isl_format format, struct isl_swizzle swizzle,1571uint32_t level, uint32_t base_layer, uint32_t layer_count,1572VkRect2D area, union isl_color_value clear_color)1573{1574assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);15751576/* We don't support planar images with multisampling yet */1577assert(image->n_planes == 1);15781579struct blorp_batch batch;1580blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);15811582struct blorp_surf surf;1583get_blorp_surf_for_anv_image(cmd_buffer->device, image, aspect,1584VK_IMAGE_USAGE_TRANSFER_DST_BIT,1585ANV_IMAGE_LAYOUT_EXPLICIT_AUX,1586aux_usage, &surf);1587anv_cmd_buffer_mark_image_written(cmd_buffer, image, aspect, aux_usage,1588level, base_layer, layer_count);15891590blorp_clear(&batch, &surf, format, anv_swizzle_for_render(swizzle),1591level, base_layer, layer_count,1592area.offset.x, area.offset.y,1593area.offset.x + area.extent.width,1594area.offset.y + area.extent.height,1595clear_color, NULL);15961597blorp_batch_finish(&batch);1598}15991600void1601anv_image_clear_depth_stencil(struct anv_cmd_buffer *cmd_buffer,1602const struct anv_image *image,1603VkImageAspectFlags aspects,1604enum isl_aux_usage depth_aux_usage,1605uint32_t level,1606uint32_t base_layer, uint32_t layer_count,1607VkRect2D area,1608float depth_value, uint8_t stencil_value)1609{1610assert(image->aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |1611VK_IMAGE_ASPECT_STENCIL_BIT));16121613struct blorp_batch batch;1614blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);16151616struct blorp_surf depth = {};1617if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {1618get_blorp_surf_for_anv_image(cmd_buffer->device,1619image, VK_IMAGE_ASPECT_DEPTH_BIT,16200, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,1621depth_aux_usage, &depth);1622}16231624struct blorp_surf stencil = {};1625if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {1626uint32_t plane = anv_image_aspect_to_plane(image->aspects,1627VK_IMAGE_ASPECT_STENCIL_BIT);1628get_blorp_surf_for_anv_image(cmd_buffer->device,1629image, VK_IMAGE_ASPECT_STENCIL_BIT,16300, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,1631image->planes[plane].aux_usage, &stencil);1632}16331634/* Blorp may choose to clear stencil using RGBA32_UINT for better1635* performance. If it does this, we need to flush it out of the depth1636* cache before rendering to it.1637*/1638anv_add_pending_pipe_bits(cmd_buffer,1639ANV_PIPE_DEPTH_CACHE_FLUSH_BIT |1640ANV_PIPE_END_OF_PIPE_SYNC_BIT,1641"before clear DS");16421643blorp_clear_depth_stencil(&batch, &depth, &stencil,1644level, base_layer, layer_count,1645area.offset.x, area.offset.y,1646area.offset.x + area.extent.width,1647area.offset.y + area.extent.height,1648aspects & VK_IMAGE_ASPECT_DEPTH_BIT,1649depth_value,1650(aspects & VK_IMAGE_ASPECT_STENCIL_BIT) ? 0xff : 0,1651stencil_value);16521653/* Blorp may choose to clear stencil using RGBA32_UINT for better1654* performance. If it does this, we need to flush it out of the render1655* cache before someone starts trying to do stencil on it.1656*/1657anv_add_pending_pipe_bits(cmd_buffer,1658ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |1659ANV_PIPE_TILE_CACHE_FLUSH_BIT |1660ANV_PIPE_END_OF_PIPE_SYNC_BIT,1661"after clear DS");16621663struct blorp_surf stencil_shadow;1664if ((aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&1665get_blorp_surf_for_anv_shadow_image(cmd_buffer->device, image,1666VK_IMAGE_ASPECT_STENCIL_BIT,1667&stencil_shadow)) {1668union isl_color_value stencil_color = {1669.u32 = { stencil_value },1670};1671blorp_clear(&batch, &stencil_shadow,1672ISL_FORMAT_R8_UINT, ISL_SWIZZLE_IDENTITY,1673level, base_layer, layer_count,1674area.offset.x, area.offset.y,1675area.offset.x + area.extent.width,1676area.offset.y + area.extent.height,1677stencil_color, NULL);1678}16791680blorp_batch_finish(&batch);1681}16821683void1684anv_image_hiz_op(struct anv_cmd_buffer *cmd_buffer,1685const struct anv_image *image,1686VkImageAspectFlagBits aspect, uint32_t level,1687uint32_t base_layer, uint32_t layer_count,1688enum isl_aux_op hiz_op)1689{1690assert(aspect == VK_IMAGE_ASPECT_DEPTH_BIT);1691assert(base_layer + layer_count <= anv_image_aux_layers(image, aspect, level));1692uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);1693assert(plane == 0);16941695struct blorp_batch batch;1696blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);16971698struct blorp_surf surf;1699get_blorp_surf_for_anv_image(cmd_buffer->device,1700image, VK_IMAGE_ASPECT_DEPTH_BIT,17010, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,1702image->planes[plane].aux_usage, &surf);17031704blorp_hiz_op(&batch, &surf, level, base_layer, layer_count, hiz_op);17051706blorp_batch_finish(&batch);1707}17081709void1710anv_image_hiz_clear(struct anv_cmd_buffer *cmd_buffer,1711const struct anv_image *image,1712VkImageAspectFlags aspects,1713uint32_t level,1714uint32_t base_layer, uint32_t layer_count,1715VkRect2D area, uint8_t stencil_value)1716{1717assert(image->aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |1718VK_IMAGE_ASPECT_STENCIL_BIT));17191720struct blorp_batch batch;1721blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);17221723struct blorp_surf depth = {};1724if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {1725uint32_t plane = anv_image_aspect_to_plane(image->aspects,1726VK_IMAGE_ASPECT_DEPTH_BIT);1727assert(base_layer + layer_count <=1728anv_image_aux_layers(image, VK_IMAGE_ASPECT_DEPTH_BIT, level));1729get_blorp_surf_for_anv_image(cmd_buffer->device,1730image, VK_IMAGE_ASPECT_DEPTH_BIT,17310, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,1732image->planes[plane].aux_usage, &depth);1733}17341735struct blorp_surf stencil = {};1736if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {1737uint32_t plane = anv_image_aspect_to_plane(image->aspects,1738VK_IMAGE_ASPECT_STENCIL_BIT);1739get_blorp_surf_for_anv_image(cmd_buffer->device,1740image, VK_IMAGE_ASPECT_STENCIL_BIT,17410, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,1742image->planes[plane].aux_usage, &stencil);1743}17441745/* From the Sky Lake PRM Volume 7, "Depth Buffer Clear":1746*1747* "The following is required when performing a depth buffer clear with1748* using the WM_STATE or 3DSTATE_WM:1749*1750* * If other rendering operations have preceded this clear, a1751* PIPE_CONTROL with depth cache flush enabled, Depth Stall bit1752* enabled must be issued before the rectangle primitive used for1753* the depth buffer clear operation.1754* * [...]"1755*1756* Even though the PRM only says that this is required if using 3DSTATE_WM1757* and a 3DPRIMITIVE, the GPU appears to also need this to avoid occasional1758* hangs when doing a clear with WM_HZ_OP.1759*/1760anv_add_pending_pipe_bits(cmd_buffer,1761ANV_PIPE_DEPTH_CACHE_FLUSH_BIT |1762ANV_PIPE_DEPTH_STALL_BIT,1763"before clear hiz");17641765blorp_hiz_clear_depth_stencil(&batch, &depth, &stencil,1766level, base_layer, layer_count,1767area.offset.x, area.offset.y,1768area.offset.x + area.extent.width,1769area.offset.y + area.extent.height,1770aspects & VK_IMAGE_ASPECT_DEPTH_BIT,1771ANV_HZ_FC_VAL,1772aspects & VK_IMAGE_ASPECT_STENCIL_BIT,1773stencil_value);17741775blorp_batch_finish(&batch);17761777/* From the SKL PRM, Depth Buffer Clear:1778*1779* "Depth Buffer Clear Workaround1780*1781* Depth buffer clear pass using any of the methods (WM_STATE,1782* 3DSTATE_WM or 3DSTATE_WM_HZ_OP) must be followed by a PIPE_CONTROL1783* command with DEPTH_STALL bit and Depth FLUSH bits “set” before1784* starting to render. DepthStall and DepthFlush are not needed between1785* consecutive depth clear passes nor is it required if the depth-clear1786* pass was done with “full_surf_clear” bit set in the1787* 3DSTATE_WM_HZ_OP."1788*1789* Even though the PRM provides a bunch of conditions under which this is1790* supposedly unnecessary, we choose to perform the flush unconditionally1791* just to be safe.1792*/1793anv_add_pending_pipe_bits(cmd_buffer,1794ANV_PIPE_DEPTH_CACHE_FLUSH_BIT |1795ANV_PIPE_DEPTH_STALL_BIT,1796"after clear hiz");1797}17981799void1800anv_image_mcs_op(struct anv_cmd_buffer *cmd_buffer,1801const struct anv_image *image,1802enum isl_format format, struct isl_swizzle swizzle,1803VkImageAspectFlagBits aspect,1804uint32_t base_layer, uint32_t layer_count,1805enum isl_aux_op mcs_op, union isl_color_value *clear_value,1806bool predicate)1807{1808assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);1809assert(image->samples > 1);1810assert(base_layer + layer_count <= anv_image_aux_layers(image, aspect, 0));18111812/* Multisampling with multi-planar formats is not supported */1813assert(image->n_planes == 1);18141815struct blorp_batch batch;1816blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer,1817BLORP_BATCH_PREDICATE_ENABLE * predicate +1818BLORP_BATCH_NO_UPDATE_CLEAR_COLOR * !clear_value);18191820struct blorp_surf surf;1821get_blorp_surf_for_anv_image(cmd_buffer->device, image, aspect,18220, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,1823ISL_AUX_USAGE_MCS, &surf);18241825/* Blorp will store the clear color for us if we provide the clear color1826* address and we are doing a fast clear. So we save the clear value into1827* the blorp surface.1828*/1829if (clear_value)1830surf.clear_color = *clear_value;18311832/* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear":1833*1834* "After Render target fast clear, pipe-control with color cache1835* write-flush must be issued before sending any DRAW commands on1836* that render target."1837*1838* This comment is a bit cryptic and doesn't really tell you what's going1839* or what's really needed. It appears that fast clear ops are not1840* properly synchronized with other drawing. This means that we cannot1841* have a fast clear operation in the pipe at the same time as other1842* regular drawing operations. We need to use a PIPE_CONTROL to ensure1843* that the contents of the previous draw hit the render target before we1844* resolve and then use a second PIPE_CONTROL after the resolve to ensure1845* that it is completed before any additional drawing occurs.1846*/1847anv_add_pending_pipe_bits(cmd_buffer,1848ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |1849ANV_PIPE_TILE_CACHE_FLUSH_BIT |1850ANV_PIPE_END_OF_PIPE_SYNC_BIT,1851"before fast clear mcs");18521853switch (mcs_op) {1854case ISL_AUX_OP_FAST_CLEAR:1855blorp_fast_clear(&batch, &surf, format, swizzle,18560, base_layer, layer_count,18570, 0, image->extent.width, image->extent.height);1858break;1859case ISL_AUX_OP_PARTIAL_RESOLVE:1860blorp_mcs_partial_resolve(&batch, &surf, format,1861base_layer, layer_count);1862break;1863case ISL_AUX_OP_FULL_RESOLVE:1864case ISL_AUX_OP_AMBIGUATE:1865default:1866unreachable("Unsupported MCS operation");1867}18681869anv_add_pending_pipe_bits(cmd_buffer,1870ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |1871ANV_PIPE_END_OF_PIPE_SYNC_BIT,1872"after fast clear mcs");18731874blorp_batch_finish(&batch);1875}18761877void1878anv_image_ccs_op(struct anv_cmd_buffer *cmd_buffer,1879const struct anv_image *image,1880enum isl_format format, struct isl_swizzle swizzle,1881VkImageAspectFlagBits aspect, uint32_t level,1882uint32_t base_layer, uint32_t layer_count,1883enum isl_aux_op ccs_op, union isl_color_value *clear_value,1884bool predicate)1885{1886assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);1887assert(image->samples == 1);1888assert(level < anv_image_aux_levels(image, aspect));1889/* Multi-LOD YcBcR is not allowed */1890assert(image->n_planes == 1 || level == 0);1891assert(base_layer + layer_count <=1892anv_image_aux_layers(image, aspect, level));18931894uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);1895uint32_t width_div = image->format->planes[plane].denominator_scales[0];1896uint32_t height_div = image->format->planes[plane].denominator_scales[1];1897uint32_t level_width = anv_minify(image->extent.width, level) / width_div;1898uint32_t level_height = anv_minify(image->extent.height, level) / height_div;18991900struct blorp_batch batch;1901blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer,1902BLORP_BATCH_PREDICATE_ENABLE * predicate +1903BLORP_BATCH_NO_UPDATE_CLEAR_COLOR * !clear_value);19041905struct blorp_surf surf;1906get_blorp_surf_for_anv_image(cmd_buffer->device, image, aspect,19070, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,1908image->planes[plane].aux_usage,1909&surf);19101911/* Blorp will store the clear color for us if we provide the clear color1912* address and we are doing a fast clear. So we save the clear value into1913* the blorp surface.1914*/1915if (clear_value)1916surf.clear_color = *clear_value;19171918/* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear":1919*1920* "After Render target fast clear, pipe-control with color cache1921* write-flush must be issued before sending any DRAW commands on1922* that render target."1923*1924* This comment is a bit cryptic and doesn't really tell you what's going1925* or what's really needed. It appears that fast clear ops are not1926* properly synchronized with other drawing. This means that we cannot1927* have a fast clear operation in the pipe at the same time as other1928* regular drawing operations. We need to use a PIPE_CONTROL to ensure1929* that the contents of the previous draw hit the render target before we1930* resolve and then use a second PIPE_CONTROL after the resolve to ensure1931* that it is completed before any additional drawing occurs.1932*/1933anv_add_pending_pipe_bits(cmd_buffer,1934ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |1935ANV_PIPE_TILE_CACHE_FLUSH_BIT |1936ANV_PIPE_END_OF_PIPE_SYNC_BIT,1937"before fast clear ccs");19381939switch (ccs_op) {1940case ISL_AUX_OP_FAST_CLEAR:1941blorp_fast_clear(&batch, &surf, format, swizzle,1942level, base_layer, layer_count,19430, 0, level_width, level_height);1944break;1945case ISL_AUX_OP_FULL_RESOLVE:1946case ISL_AUX_OP_PARTIAL_RESOLVE:1947blorp_ccs_resolve(&batch, &surf, level, base_layer, layer_count,1948format, ccs_op);1949break;1950case ISL_AUX_OP_AMBIGUATE:1951for (uint32_t a = 0; a < layer_count; a++) {1952const uint32_t layer = base_layer + a;1953blorp_ccs_ambiguate(&batch, &surf, level, layer);1954}1955break;1956default:1957unreachable("Unsupported CCS operation");1958}19591960anv_add_pending_pipe_bits(cmd_buffer,1961ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |1962ANV_PIPE_END_OF_PIPE_SYNC_BIT,1963"after fast clear ccs");19641965blorp_batch_finish(&batch);1966}196719681969