This adds an aux_surface member to anv_image as well as the various bits of plumbing required to initialize them in BindImageMemory, keep track of the aux_usage, and add the surface state relocations.
Signed-off-by: Jason Ekstrand <ja...@jlekstrand.net> --- src/intel/vulkan/anv_cmd_buffer.c | 28 +++++++++++++++++++++++++--- src/intel/vulkan/anv_device.c | 3 +++ src/intel/vulkan/anv_image.c | 19 ++++++++++++++++++- src/intel/vulkan/anv_private.h | 6 ++++++ 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index 34109c9..e5ab7d0 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -693,6 +693,7 @@ add_surface_state_reloc(struct anv_cmd_buffer *cmd_buffer, static void add_image_view_relocs(struct anv_cmd_buffer *cmd_buffer, const struct anv_image_view *iview, + enum isl_aux_usage aux_usage, struct anv_state state) { const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev; @@ -700,6 +701,22 @@ add_image_view_relocs(struct anv_cmd_buffer *cmd_buffer, anv_reloc_list_add(&cmd_buffer->surface_relocs, &cmd_buffer->pool->alloc, state.offset + isl_dev->ss.addr_offset, iview->bo, iview->offset); + + if (aux_usage != ISL_AUX_USAGE_NONE) { + uint32_t aux_offset = iview->offset + iview->image->aux_surface.offset; + + /* On gen7 and prior, the bottom 12 bits of the MCS base address are + * used to store other information. This should be ok, however, because + * surface buffer addresses are always 4K page alinged. + */ + assert((aux_offset & 0xfff) == 0); + uint32_t *aux_addr_dw = state.map + isl_dev->ss.aux_addr_offset; + aux_offset += *aux_addr_dw & 0xfff; + + anv_reloc_list_add(&cmd_buffer->surface_relocs, &cmd_buffer->pool->alloc, + state.offset + isl_dev->ss.aux_addr_offset, + iview->bo, aux_offset); + } } enum isl_format @@ -827,7 +844,8 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, surface_state.offset += fb_att->rt_state_offset; surface_state.map += fb_att->rt_state_offset; - add_image_view_relocs(cmd_buffer, fb_att->view, surface_state); + add_image_view_relocs(cmd_buffer, fb_att->view, fb_att->aux_usage, + surface_state); } else { /* Null render target */ struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; @@ -854,13 +872,17 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: surface_state = desc->image_view->sampler_surface_state; assert(surface_state.alloc_size); - add_image_view_relocs(cmd_buffer, desc->image_view, surface_state); + add_image_view_relocs(cmd_buffer, desc->image_view, + desc->image_view->image->aux_usage, + surface_state); break; case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: { surface_state = desc->image_view->storage_surface_state; assert(surface_state.alloc_size); - add_image_view_relocs(cmd_buffer, desc->image_view, surface_state); + add_image_view_relocs(cmd_buffer, desc->image_view, + desc->image_view->image->aux_usage, + surface_state); struct brw_image_param *image_param = &cmd_buffer->state.push_constants[stage]->images[image++]; diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 5780894..3d4b783 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -1789,6 +1789,7 @@ VkResult anv_CreateFramebuffer( ANV_FROM_HANDLE(anv_image_view, iview, pCreateInfo->pAttachments[i]); framebuffer->attachments[i].view = iview; + framebuffer->attachments[i].aux_usage = iview->image->aux_usage; framebuffer->attachments[i].rt_state_offset = -1; if (iview->image->aspects & VK_IMAGE_ASPECT_COLOR_BIT) @@ -1812,6 +1813,8 @@ VkResult anv_CreateFramebuffer( framebuffer->surface_states.map + offset, .surf = &iview->image->color_surface.isl, .view = &isl_view, + .aux_surf = &iview->image->aux_surface.isl, + .aux_usage = fb_att->aux_usage, .mocs = device->default_mocs); } } diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index d814411..405b923 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -248,6 +248,7 @@ anv_image_create(VkDevice _device, image->samples = pCreateInfo->samples; image->usage = anv_image_get_full_usage(pCreateInfo, image->aspects); image->tiling = pCreateInfo->tiling; + image->aux_usage = ISL_AUX_USAGE_NONE; uint32_t b; for_each_bit(b, image->aspects) { @@ -291,17 +292,33 @@ anv_DestroyImage(VkDevice _device, VkImage _image, } VkResult anv_BindImageMemory( - VkDevice device, + VkDevice _device, VkImage _image, VkDeviceMemory _memory, VkDeviceSize memoryOffset) { + ANV_FROM_HANDLE(anv_device, device, _device); ANV_FROM_HANDLE(anv_device_memory, mem, _memory); ANV_FROM_HANDLE(anv_image, image, _image); if (mem) { image->bo = &mem->bo; image->offset = memoryOffset; + + if (image->aux_surface.isl.size > 0) { + /* Auxiliary surfaces need to have their memory initialized before + * they can be used. HiZ is particularly bad, where garbage data can + * lead go GPU hangs. + */ + void *map = anv_gem_mmap(device, image->bo->gem_handle, + image->offset + image->aux_surface.offset, + image->aux_surface.isl.size, + device->info.has_llc ? 0 : I915_MMAP_WC); + + memset(map, 0, image->aux_surface.isl.size); + + anv_gem_munmap(map, image->aux_surface.isl.size); + } } else { image->bo = NULL; image->offset = 0; diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 4046c6c..5c24c37 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1700,6 +1700,11 @@ struct anv_image { struct anv_surface stencil_surface; }; }; + + /** The usage of the aux surface when not in a renderpass. */ + enum isl_aux_usage aux_usage; + + struct anv_surface aux_surface; }; static inline uint32_t @@ -1835,6 +1840,7 @@ struct anv_sampler { struct anv_framebuffer_attachment { struct anv_image_view * view; + enum isl_aux_usage aux_usage; int16_t rt_state_offset; }; -- 2.5.0.400.gff86faf _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev