[Mesa-dev] [PATCH 07/22] anv/image: Initialize the clear values buffer
Nanley Chery
nanleychery at gmail.com
Thu May 11 18:12:04 UTC 2017
On Tue, May 02, 2017 at 04:03:36PM -0700, Jason Ekstrand wrote:
> On Thu, Apr 27, 2017 at 11:32 AM, Nanley Chery <nanleychery at gmail.com>
> wrote:
>
> > Signed-off-by: Nanley Chery <nanley.g.chery at intel.com>
> > ---
> > src/intel/vulkan/anv_image.c | 75 ++++++++++++++++++++++++++++++
> > +++++-------
> > src/intel/vulkan/anv_private.h | 5 +++
> > 2 files changed, 69 insertions(+), 11 deletions(-)
> >
> > diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
> > index 9f3eb52a37..751f2d6026 100644
> > --- a/src/intel/vulkan/anv_image.c
> > +++ b/src/intel/vulkan/anv_image.c
> > @@ -179,6 +179,37 @@ add_clear_value_buffer(struct anv_image * const image,
> > image->size += device->isl_dev.ss.size * anv_color_aux_levels(image);
> > }
> >
> > +/* Populates a buffer with a surface state object that can be used for
> > + * resolving the specified subresource of a CCS buffer.
> > + */
> > +void
> > +anv_fill_ccs_resolve_ss(const struct anv_device * const device,
> > + void * const data, const struct anv_image * const
> > image,
> > + const uint8_t level, const uint32_t layer)
> > +{
> > + assert(device && image && data);
> > +
> > + /* The image subresource must have a color auxiliary buffer. */
> > + assert(level < anv_color_aux_levels(image));
> > + assert(layer < anv_color_aux_layers(image, level));
> > +
> > + isl_surf_fill_state(&device->isl_dev, data,
> > + .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 = layer,
> > + .array_len = 1,
> > + },
> > + .aux_surf = &image->aux_surface.isl,
> > + .aux_usage = image->aux_usage ==
> > ISL_AUX_USAGE_NONE ?
> > + ISL_AUX_USAGE_CCS_D :
> > image->aux_usage,
> > + .mocs = device->default_mocs);
> > +}
> > +
> > /**
> > * Initialize the anv_image::*_surface selected by \a aspect. Then update
> > the
> > * image's memory requirements (that is, the image's size and alignment).
> > @@ -411,6 +442,9 @@ VkResult anv_BindImageMemory(
> > image->bo = &mem->bo;
> > image->offset = memoryOffset;
> >
> > + /* The data after the main surface must be initialized for various
> > + * reasons.
> > + */
> > if (image->aux_surface.isl.size > 0) {
> >
> > /* The offset must be a multiple of 4K or else the anv_gem_mmap call
> > @@ -418,16 +452,11 @@ VkResult anv_BindImageMemory(
> > */
> > assert((image->offset + image->aux_surface.offset) % 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->aux_surface.offset,
> > - image->aux_surface.isl.size,
> > - device->info.has_llc ? 0 : I915_MMAP_WC);
> > + const uint32_t image_map_size = image->size -
> > image->aux_surface.offset;
> > + void * const map = anv_gem_mmap(device, image->bo->gem_handle,
> > + image->offset +
> > image->aux_surface.offset,
> > + image_map_size,
> > + device->info.has_llc ? 0 :
> > I915_MMAP_WC);
> >
> > /* If anv_gem_mmap returns NULL, it's likely that the kernel was
> > * not able to find space on the host to create a proper mapping.
> > @@ -435,9 +464,33 @@ VkResult anv_BindImageMemory(
> > if (map == NULL)
> > return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
> >
> > + /* 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.
> > + */
> > memset(map, 0, image->aux_surface.isl.size);
> >
> > - anv_gem_munmap(map, image->aux_surface.isl.size);
> > + /* For color auxiliary surfaces, the clear values buffer must be
> > + * initialized. This is because a render pass attachment's loadOp
> > may be
> > + * LOAD_OP_LOAD, triggering a GPU memcpy from the clear values
> > buffer
> > + * into the surface state object. Pre-SKL, the dword containing the
> > clear
> > + * values also contains other fields, so we need to initialize those
> > + * fields to match the values for a color attachment. On SKL+, the
> > MCS
> > + * surface state only allows 1/0 clear colors. Using the fill
> > function
> > + * for a CCS resolve state also gives the desired result for MCS
> > images.
> > + */
> >
>
> Ugh... So, I now have a good argument for not storing full surface states
> but I don't really like it....
>
> Short version: We really badly need to stop initializing things from the
> CPU in BindImageMemory.
>
> Longer version: Vulkan allows the client to alias memory. In other words,
> they can have, for instance a depth image and a color image bound to
> overlapping memory locations so long as they transition things properly.
> In particular, if they most recently used it as a color image and they want
> to use it as a depth image, they have to transition from UNDEFINED to
> whatever layout they want. Then, when they want to go back to using the
> depth image, they transition it from UNDEFINED to whatever. This may sound
> crazy but it can allow an application to significantly reduce its memory
> footprint if it has temporary images that it uses in its rendering pipeline
> but never at the same time. Today, thanks to memset hacks, we don't
> support this properly.
>
> We really need to switch depth and color over to doing the initialization
> during the UNDEFINED -> whatever layout transition instead of the memset.
> For the clear color values, this means that we need to either initialize
> the whole thing from the GPU on the UNDEFINED transition or else we need to
> make sure that we don't store anything important in the clear color values
> other than the clear color itself. It should be fairly easy to use the CS
> ALU to mask the clear color and OR it into the surface state packet.
>
>
Agreed.
More information about the mesa-dev
mailing list