[Mesa-dev] [PATCH 12/13] anv: Add some basic infrastructure for aux surfaces
Jason Ekstrand
jason at jlekstrand.net
Sun Sep 25 16:59:11 UTC 2016
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 <jason at 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
More information about the mesa-dev
mailing list