<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Sep 25, 2016 at 9:59 AM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This enables lossless render target compression but only for first mip level<br>
of the first slice and only within a render pass. At the end of the render<br>
pass it always does a full resolve.<br>
<br>
Signed-off-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br>
---<br>
src/intel/vulkan/anv_blorp.c | 30 ++++++++++++++++++++++++++++<br>
src/intel/vulkan/anv_device.c | 40 ++++++++++++++++++++++++++++++<wbr>++------<br>
src/intel/vulkan/anv_image.c | 9 +++++++++<br>
src/intel/vulkan/anv_private.h | 2 ++<br>
src/intel/vulkan/genX_cmd_<wbr>buffer.c | 17 ++++++++++++++++<br>
5 files changed, 92 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c<br>
index 5cc19eb..74f1d80 100644<br>
--- a/src/intel/vulkan/anv_blorp.c<br>
+++ b/src/intel/vulkan/anv_blorp.c<br>
@@ -929,3 +929,33 @@ anv_cmd_buffer_resolve_<wbr>subpass(struct anv_cmd_buffer *cmd_buffer)<br>
<br>
blorp_batch_finish(&batch);<br>
}<br>
+<br>
+void<br>
+anv_cmd_buffer_resolve_<wbr>framebuffer(struct anv_cmd_buffer *cmd_buffer,<br>
+ struct anv_framebuffer *fb)<br>
+{<br>
+ struct blorp_batch batch;<br>
+ blorp_batch_init(&cmd_buffer-><wbr>device->blorp, &batch, cmd_buffer);<br>
+<br>
+ for (uint32_t i = 0; i < fb->attachment_count; i++) {<br>
+ struct anv_framebuffer_attachment *fb_att = &fb->attachments[i];<br>
+ const struct anv_image *image = fb_att->view->image;<br>
+<br>
+ if (fb_att->aux_usage != ISL_AUX_USAGE_CCS_E &&<br>
+ fb_att->aux_usage != ISL_AUX_USAGE_CCS_D)<br>
+ continue;<br>
+<br>
+ struct blorp_surf surf;<br>
+ get_blorp_surf_for_anv_image(<wbr>image, VK_IMAGE_ASPECT_COLOR_BIT, &surf);<br>
+ surf.aux_surf = &image->aux_surface.isl;<br>
+ surf.aux_addr = (struct blorp_address) {<br>
+ .buffer = image->bo,<br>
+ .offset = image->offset + image->aux_surface.offset,<br>
+ };<br>
+ surf.aux_usage = fb_att->aux_usage;<br>
+<br>
+ blorp_ccs_resolve(&batch, &surf, fb_att->view->isl.format);<br>
+ }<br>
+<br>
+ blorp_batch_finish(&batch);<br>
+}<br>
diff --git a/src/intel/vulkan/anv_device.<wbr>c b/src/intel/vulkan/anv_device.<wbr>c<br>
index 3d4b783..8c68e94 100644<br>
--- a/src/intel/vulkan/anv_device.<wbr>c<br>
+++ b/src/intel/vulkan/anv_device.<wbr>c<br>
@@ -1765,6 +1765,30 @@ void anv_DestroySampler(<br>
anv_free2(&device->alloc, pAllocator, sampler);<br>
}<br>
<br>
+static enum isl_aux_usage<br>
+get_fb_attachment_aux_usage(<wbr>struct anv_device *device,<br>
+ struct anv_framebuffer *fb,<br>
+ struct anv_framebuffer_attachment *fb_att)<br>
+{<br>
+ if (fb_att->view->image->aux_<wbr>surface.isl.size == 0)<br>
+ return ISL_AUX_USAGE_NONE; /* No aux surface */<br>
+<br>
+ /* This is a color buffer, it had better be CCS */<br>
+ assert(fb_att->view->image-><wbr>aux_surface.isl.usage & ISL_SURF_USAGE_CCS_BIT);<br>
+<br>
+ if (!isl_format_supports_<wbr>lossless_compression(&device-><wbr>info,<br>
+ fb_att->view->isl.format))<br>
+ return ISL_AUX_USAGE_NONE; /* Unsupported format */<br>
+<br>
+ if (fb->layers > 1 || fb_att->view->isl.base_array_<wbr>layer > 0)<br>
+ return ISL_AUX_USAGE_NONE; /* Multi-layered CCS not yet supported */<br>
+<br>
+ if (fb_att->view->isl.base_level > 0)<br>
+ return ISL_AUX_USAGE_NONE; /* Multi-LOD CCS not yet supported */<br>
+<br>
+ return ISL_AUX_USAGE_CCS_E;<br>
+}<br>
+<br>
VkResult anv_CreateFramebuffer(<br>
VkDevice _device,<br>
const VkFramebufferCreateInfo* pCreateInfo,<br>
@@ -1783,6 +1807,10 @@ VkResult anv_CreateFramebuffer(<br>
if (framebuffer == NULL)<br>
return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
<br>
+ framebuffer->width = pCreateInfo->width;<br>
+ framebuffer->height = pCreateInfo->height;<br>
+ framebuffer->layers = pCreateInfo->layers;<br>
+<br>
framebuffer->attachment_count = pCreateInfo->attachmentCount;<br>
unsigned color_count = 0;<br>
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {<br>
@@ -1802,10 +1830,14 @@ VkResult anv_CreateFramebuffer(<br>
device->isl_dev.ss.align);<br>
unsigned color_idx = 0;<br>
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {<br>
- struct anv_image_view *iview = framebuffer->attachments[i].<wbr>view;<br>
+ struct anv_framebuffer_attachment *fb_att = &framebuffer->attachments[i];<br>
+ struct anv_image_view *iview = fb_att->view;<br>
+<br>
if (iview->image->aspects & VK_IMAGE_ASPECT_COLOR_BIT) {<br>
const uint16_t offset = (color_idx++) * device->isl_dev.ss.align;<br>
- framebuffer->attachments[i].<wbr>rt_state_offset = offset;<br>
+ fb_att->rt_state_offset = offset;<br>
+ fb_att->aux_usage =<br>
+ get_fb_attachment_aux_usage(<wbr>device, framebuffer, fb_att);<br>
<br>
struct isl_view isl_view = iview->isl;<br>
isl_view.usage |= ISL_SURF_USAGE_RENDER_TARGET_<wbr>BIT;<br>
@@ -1822,10 +1854,6 @@ VkResult anv_CreateFramebuffer(<br>
if (device->info.has_llc)<br>
anv_state_clflush(framebuffer-<wbr>>surface_states);<br>
<br>
- framebuffer->width = pCreateInfo->width;<br>
- framebuffer->height = pCreateInfo->height;<br>
- framebuffer->layers = pCreateInfo->layers;<br>
-<br>
*pFramebuffer = anv_framebuffer_to_handle(<wbr>framebuffer);<br>
<br>
return VK_SUCCESS;<br>
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c<br>
index 405b923..ff99126 100644<br>
--- a/src/intel/vulkan/anv_image.c<br>
+++ b/src/intel/vulkan/anv_image.c<br>
@@ -169,6 +169,15 @@ make_surface(const struct anv_device *dev,<br>
<br>
add_surface(image, anv_surf);<br>
<br>
+ if (aspect == VK_IMAGE_ASPECT_COLOR_BIT) {<br>
+ if (dev->info.gen >= 9 && vk_info->samples == 1) {<br>
+ ok = isl_surf_get_ccs_surf(&dev-><wbr>isl_dev, &anv_surf->isl,<br>
+ &image->aux_surface.isl);<br>
+ if (ok)<br>
+ add_surface(image, &image->aux_surface);<br>
+ }<br>
+ }<br>
+<br>
return VK_SUCCESS;<br>
}<br>
<br>
diff --git a/src/intel/vulkan/anv_<wbr>private.h b/src/intel/vulkan/anv_<wbr>private.h<br>
index 5c24c37..5f03ae0 100644<br>
--- a/src/intel/vulkan/anv_<wbr>private.h<br>
+++ b/src/intel/vulkan/anv_<wbr>private.h<br>
@@ -1405,6 +1405,8 @@ anv_cmd_buffer_cs_push_<wbr>constants(struct anv_cmd_buffer *cmd_buffer);<br>
<br>
void anv_cmd_buffer_clear_subpass(<wbr>struct anv_cmd_buffer *cmd_buffer);<br>
void anv_cmd_buffer_resolve_<wbr>subpass(struct anv_cmd_buffer *cmd_buffer);<br>
+void anv_cmd_buffer_resolve_<wbr>framebuffer(struct anv_cmd_buffer *cmd_buffer,<br>
+ struct anv_framebuffer *fb);<br>
<br>
const struct anv_image_view *<br>
anv_cmd_buffer_get_depth_<wbr>stencil_view(const struct anv_cmd_buffer *cmd_buffer);<br>
diff --git a/src/intel/vulkan/genX_cmd_<wbr>buffer.c b/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
index 90700e7..0962118 100644<br>
--- a/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
+++ b/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
@@ -1346,6 +1346,23 @@ void genX(CmdEndRenderPass)(<br>
<br>
anv_cmd_buffer_resolve_<wbr>subpass(cmd_buffer);<br>
<br>
+ /* From the Sky Lake PRM Vol. 7, "Render Target Resolve":<br>
+ *<br>
+ * "When performing a render target resolve, PIPE_CONTROL with end of<br>
+ * pipe sync must be delivered."<br>
+ *<br>
+ * By "end of pipe sync" it appears that they mean a pixel scoreboard stall<br>
+ * This makes sense because the resolve operation probably needs the CCS to<br>
+ * be fully valid before it looks at it.<br>
+ */<br>
+ anv_batch_emit(&cmd_buffer-><wbr>batch, GENX(PIPE_CONTROL), pc) {<br>
+ pc.StallAtPixelScoreboard = true;<br>
+ pc.CommandStreamerStallEnable = true;<br>
+ }<br></blockquote><div><br></div><div>Topi,<br></div><div><br></div><div>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?<br><br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+ anv_cmd_buffer_resolve_<wbr>framebuffer(cmd_buffer,<br>
+ cmd_buffer->state.framebuffer)<wbr>;<br>
+<br>
#ifndef NDEBUG<br>
anv_dump_add_framebuffer(cmd_<wbr>buffer, cmd_buffer->state.framebuffer)<wbr>;<br>
#endif<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.5.0.400.gff86faf<br>
<br>
</font></span></blockquote></div><br></div></div>