[Mesa-dev] [PATCH 13/13] anv: Enable CCS for basic cases
Jason Ekstrand
jason at jlekstrand.net
Sun Sep 25 17:11:55 UTC 2016
On Sun, Sep 25, 2016 at 9:59 AM, Jason Ekstrand <jason at jlekstrand.net>
wrote:
> This enables lossless render target compression but only for first mip
> level
> of the first slice and only within a render pass. At the end of the render
> pass it always does a full resolve.
>
> Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
> ---
> src/intel/vulkan/anv_blorp.c | 30 ++++++++++++++++++++++++++++
> src/intel/vulkan/anv_device.c | 40 ++++++++++++++++++++++++++++++
> ++------
> src/intel/vulkan/anv_image.c | 9 +++++++++
> src/intel/vulkan/anv_private.h | 2 ++
> src/intel/vulkan/genX_cmd_buffer.c | 17 ++++++++++++++++
> 5 files changed, 92 insertions(+), 6 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c
> index 5cc19eb..74f1d80 100644
> --- a/src/intel/vulkan/anv_blorp.c
> +++ b/src/intel/vulkan/anv_blorp.c
> @@ -929,3 +929,33 @@ anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer
> *cmd_buffer)
>
> blorp_batch_finish(&batch);
> }
> +
> +void
> +anv_cmd_buffer_resolve_framebuffer(struct anv_cmd_buffer *cmd_buffer,
> + struct anv_framebuffer *fb)
> +{
> + struct blorp_batch batch;
> + blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer);
> +
> + for (uint32_t i = 0; i < fb->attachment_count; i++) {
> + struct anv_framebuffer_attachment *fb_att = &fb->attachments[i];
> + const struct anv_image *image = fb_att->view->image;
> +
> + if (fb_att->aux_usage != ISL_AUX_USAGE_CCS_E &&
> + fb_att->aux_usage != ISL_AUX_USAGE_CCS_D)
> + continue;
> +
> + struct blorp_surf surf;
> + get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT,
> &surf);
> + surf.aux_surf = &image->aux_surface.isl;
> + surf.aux_addr = (struct blorp_address) {
> + .buffer = image->bo,
> + .offset = image->offset + image->aux_surface.offset,
> + };
> + surf.aux_usage = fb_att->aux_usage;
> +
> + blorp_ccs_resolve(&batch, &surf, fb_att->view->isl.format);
> + }
> +
> + blorp_batch_finish(&batch);
> +}
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index 3d4b783..8c68e94 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -1765,6 +1765,30 @@ void anv_DestroySampler(
> anv_free2(&device->alloc, pAllocator, sampler);
> }
>
> +static enum isl_aux_usage
> +get_fb_attachment_aux_usage(struct anv_device *device,
> + struct anv_framebuffer *fb,
> + struct anv_framebuffer_attachment *fb_att)
> +{
> + if (fb_att->view->image->aux_surface.isl.size == 0)
> + return ISL_AUX_USAGE_NONE; /* No aux surface */
> +
> + /* This is a color buffer, it had better be CCS */
> + assert(fb_att->view->image->aux_surface.isl.usage &
> ISL_SURF_USAGE_CCS_BIT);
> +
> + if (!isl_format_supports_lossless_compression(&device->info,
> +
> fb_att->view->isl.format))
> + return ISL_AUX_USAGE_NONE; /* Unsupported format */
> +
> + if (fb->layers > 1 || fb_att->view->isl.base_array_layer > 0)
> + return ISL_AUX_USAGE_NONE; /* Multi-layered CCS not yet supported */
> +
> + if (fb_att->view->isl.base_level > 0)
> + return ISL_AUX_USAGE_NONE; /* Multi-LOD CCS not yet supported */
> +
> + return ISL_AUX_USAGE_CCS_E;
> +}
> +
> VkResult anv_CreateFramebuffer(
> VkDevice _device,
> const VkFramebufferCreateInfo* pCreateInfo,
> @@ -1783,6 +1807,10 @@ VkResult anv_CreateFramebuffer(
> if (framebuffer == NULL)
> return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
>
> + framebuffer->width = pCreateInfo->width;
> + framebuffer->height = pCreateInfo->height;
> + framebuffer->layers = pCreateInfo->layers;
> +
> framebuffer->attachment_count = pCreateInfo->attachmentCount;
> unsigned color_count = 0;
> for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
> @@ -1802,10 +1830,14 @@ VkResult anv_CreateFramebuffer(
> device->isl_dev.ss.align);
> unsigned color_idx = 0;
> for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
> - struct anv_image_view *iview = framebuffer->attachments[i].view;
> + struct anv_framebuffer_attachment *fb_att =
> &framebuffer->attachments[i];
> + struct anv_image_view *iview = fb_att->view;
> +
> if (iview->image->aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
> const uint16_t offset = (color_idx++) * device->isl_dev.ss.align;
> - framebuffer->attachments[i].rt_state_offset = offset;
> + fb_att->rt_state_offset = offset;
> + fb_att->aux_usage =
> + get_fb_attachment_aux_usage(device, framebuffer, fb_att);
>
> struct isl_view isl_view = iview->isl;
> isl_view.usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
> @@ -1822,10 +1854,6 @@ VkResult anv_CreateFramebuffer(
> if (device->info.has_llc)
> anv_state_clflush(framebuffer->surface_states);
>
> - framebuffer->width = pCreateInfo->width;
> - framebuffer->height = pCreateInfo->height;
> - framebuffer->layers = pCreateInfo->layers;
> -
> *pFramebuffer = anv_framebuffer_to_handle(framebuffer);
>
> return VK_SUCCESS;
> diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
> index 405b923..ff99126 100644
> --- a/src/intel/vulkan/anv_image.c
> +++ b/src/intel/vulkan/anv_image.c
> @@ -169,6 +169,15 @@ make_surface(const struct anv_device *dev,
>
> add_surface(image, anv_surf);
>
> + if (aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
> + if (dev->info.gen >= 9 && vk_info->samples == 1) {
> + ok = isl_surf_get_ccs_surf(&dev->isl_dev, &anv_surf->isl,
> + &image->aux_surface.isl);
> + if (ok)
> + add_surface(image, &image->aux_surface);
> + }
> + }
> +
> return VK_SUCCESS;
> }
>
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_
> private.h
> index 5c24c37..5f03ae0 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -1405,6 +1405,8 @@ anv_cmd_buffer_cs_push_constants(struct
> anv_cmd_buffer *cmd_buffer);
>
> void anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer);
> void anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer);
> +void anv_cmd_buffer_resolve_framebuffer(struct anv_cmd_buffer
> *cmd_buffer,
> + struct anv_framebuffer *fb);
>
> const struct anv_image_view *
> anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer
> *cmd_buffer);
> diff --git a/src/intel/vulkan/genX_cmd_buffer.c
> b/src/intel/vulkan/genX_cmd_buffer.c
> index 90700e7..0962118 100644
> --- a/src/intel/vulkan/genX_cmd_buffer.c
> +++ b/src/intel/vulkan/genX_cmd_buffer.c
> @@ -1346,6 +1346,23 @@ void genX(CmdEndRenderPass)(
>
> anv_cmd_buffer_resolve_subpass(cmd_buffer);
>
> + /* From the Sky Lake PRM Vol. 7, "Render Target Resolve":
> + *
> + * "When performing a render target resolve, PIPE_CONTROL with end
> of
> + * pipe sync must be delivered."
> + *
> + * By "end of pipe sync" it appears that they mean a pixel scoreboard
> stall
> + * This makes sense because the resolve operation probably needs the
> CCS to
> + * be fully valid before it looks at it.
> + */
> + anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
> + pc.StallAtPixelScoreboard = true;
> + pc.CommandStreamerStallEnable = true;
> + }
>
Topi,
I found this little nugget in the PRM. It doesn't look like we're doing
that in the GL driver. Maybe it has something to do with your problem?
--Jason
> +
> + anv_cmd_buffer_resolve_framebuffer(cmd_buffer,
> + cmd_buffer->state.framebuffer);
> +
> #ifndef NDEBUG
> anv_dump_add_framebuffer(cmd_buffer, cmd_buffer->state.framebuffer);
> #endif
> --
> 2.5.0.400.gff86faf
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20160925/d7715724/attachment-0001.html>
More information about the mesa-dev
mailing list