summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vulkan/gen7_cmd_buffer.c170
-rw-r--r--src/vulkan/gen8_cmd_buffer.c173
-rw-r--r--src/vulkan/genX_cmd_buffer.c179
3 files changed, 179 insertions, 343 deletions
diff --git a/src/vulkan/gen7_cmd_buffer.c b/src/vulkan/gen7_cmd_buffer.c
index 18b36487c5f..7c12394b088 100644
--- a/src/vulkan/gen7_cmd_buffer.c
+++ b/src/vulkan/gen7_cmd_buffer.c
@@ -556,176 +556,6 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
cmd_buffer->state.dirty = 0;
}
-static void
-cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
-{
- struct anv_device *device = cmd_buffer->device;
- const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
- const struct anv_image_view *iview =
- anv_cmd_buffer_get_depth_stencil_view(cmd_buffer);
- const struct anv_image *image = iview ? iview->image : NULL;
- const struct anv_format *anv_format =
- iview ? anv_format_for_vk_format(iview->vk_format) : NULL;
- const bool has_depth = iview && anv_format->has_depth;
- const bool has_stencil = iview && anv_format->has_stencil;
-
- /* Emit 3DSTATE_DEPTH_BUFFER */
- if (has_depth) {
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DEPTH_BUFFER),
- .SurfaceType = SURFTYPE_2D,
- .DepthWriteEnable = true,
- .StencilWriteEnable = has_stencil,
- .HierarchicalDepthBufferEnable = false,
- .SurfaceFormat = isl_surf_get_depth_format(&device->isl_dev,
- &image->depth_surface.isl),
- .SurfacePitch = image->depth_surface.isl.row_pitch - 1,
- .SurfaceBaseAddress = {
- .bo = image->bo,
- .offset = image->depth_surface.offset,
- },
- .Height = fb->height - 1,
- .Width = fb->width - 1,
- .LOD = 0,
- .Depth = 1 - 1,
- .MinimumArrayElement = 0,
- .DepthBufferObjectControlState = GENX(MOCS),
- .RenderTargetViewExtent = 1 - 1);
- } else {
- /* Even when no depth buffer is present, the hardware requires that
- * 3DSTATE_DEPTH_BUFFER be programmed correctly. The Broadwell PRM says:
- *
- * If a null depth buffer is bound, the driver must instead bind depth as:
- * 3DSTATE_DEPTH.SurfaceType = SURFTYPE_2D
- * 3DSTATE_DEPTH.Width = 1
- * 3DSTATE_DEPTH.Height = 1
- * 3DSTATE_DEPTH.SuraceFormat = D16_UNORM
- * 3DSTATE_DEPTH.SurfaceBaseAddress = 0
- * 3DSTATE_DEPTH.HierarchicalDepthBufferEnable = 0
- * 3DSTATE_WM_DEPTH_STENCIL.DepthTestEnable = 0
- * 3DSTATE_WM_DEPTH_STENCIL.DepthBufferWriteEnable = 0
- *
- * The PRM is wrong, though. The width and height must be programmed to
- * actual framebuffer's width and height, even when neither depth buffer
- * nor stencil buffer is present.
- */
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DEPTH_BUFFER),
- .SurfaceType = SURFTYPE_2D,
- .SurfaceFormat = D16_UNORM,
- .Width = fb->width - 1,
- .Height = fb->height - 1,
- .StencilWriteEnable = has_stencil);
- }
-
- /* Emit 3DSTATE_STENCIL_BUFFER */
- if (has_stencil) {
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_STENCIL_BUFFER),
-# if (ANV_IS_HASWELL)
- .StencilBufferEnable = true,
-# endif
- .StencilBufferObjectControlState = GENX(MOCS),
-
- /* Stencil buffers have strange pitch. The PRM says:
- *
- * The pitch must be set to 2x the value computed based on width,
- * as the stencil buffer is stored with two rows interleaved.
- */
- .SurfacePitch = 2 * image->stencil_surface.isl.row_pitch - 1,
-
- .SurfaceBaseAddress = {
- .bo = image->bo,
- .offset = image->offset + image->stencil_surface.offset,
- });
- } else {
- anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_STENCIL_BUFFER);
- }
-
- /* Disable hierarchial depth buffers. */
- anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_HIER_DEPTH_BUFFER);
-
- /* Clear the clear params. */
- anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_CLEAR_PARAMS);
-}
-
-/**
- * @see anv_cmd_buffer_set_subpass()
- */
-GENX_FUNC(GEN7, GEN7) void
-genX(cmd_buffer_set_subpass)(struct anv_cmd_buffer *cmd_buffer,
- struct anv_subpass *subpass)
-{
- cmd_buffer->state.subpass = subpass;
- cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
- cmd_buffer->state.dirty |= ANV_CMD_DIRTY_RENDER_TARGETS;
-
- cmd_buffer_emit_depth_stencil(cmd_buffer);
-}
-
-void genX(CmdBeginRenderPass)(
- VkCommandBuffer commandBuffer,
- const VkRenderPassBeginInfo* pRenderPassBegin,
- VkSubpassContents contents)
-{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
- ANV_FROM_HANDLE(anv_render_pass, pass, pRenderPassBegin->renderPass);
- ANV_FROM_HANDLE(anv_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
-
- cmd_buffer->state.framebuffer = framebuffer;
- cmd_buffer->state.pass = pass;
- anv_cmd_state_setup_attachments(cmd_buffer, pRenderPassBegin);
-
- genX(flush_pipeline_select_3d)(cmd_buffer);
-
- const VkRect2D *render_area = &pRenderPassBegin->renderArea;
-
- anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_DRAWING_RECTANGLE,
- .ClippedDrawingRectangleYMin = render_area->offset.y,
- .ClippedDrawingRectangleXMin = render_area->offset.x,
- .ClippedDrawingRectangleYMax =
- render_area->offset.y + render_area->extent.height - 1,
- .ClippedDrawingRectangleXMax =
- render_area->offset.x + render_area->extent.width - 1,
- .DrawingRectangleOriginY = 0,
- .DrawingRectangleOriginX = 0);
-
- gen7_cmd_buffer_set_subpass(cmd_buffer, pass->subpasses);
- anv_cmd_buffer_clear_subpass(cmd_buffer);
-}
-
-void genX(CmdNextSubpass)(
- VkCommandBuffer commandBuffer,
- VkSubpassContents contents)
-{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-
- assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
-
- anv_cmd_buffer_resolve_subpass(cmd_buffer);
- gen7_cmd_buffer_set_subpass(cmd_buffer, cmd_buffer->state.subpass + 1);
- anv_cmd_buffer_clear_subpass(cmd_buffer);
-}
-
-void genX(CmdEndRenderPass)(
- VkCommandBuffer commandBuffer)
-{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-
- anv_cmd_buffer_resolve_subpass(cmd_buffer);
-
- /* Emit a flushing pipe control at the end of a pass. This is kind of a
- * hack but it ensures that render targets always actually get written.
- * Eventually, we should do flushing based on image format transitions
- * or something of that nature.
- */
- anv_batch_emit(&cmd_buffer->batch, GEN7_PIPE_CONTROL,
- .PostSyncOperation = NoWrite,
- .RenderTargetCacheFlushEnable = true,
- .InstructionCacheInvalidateEnable = true,
- .DepthCacheFlushEnable = true,
- .VFCacheInvalidationEnable = true,
- .TextureCacheInvalidationEnable = true,
- .CommandStreamerStallEnable = true);
-}
-
void genX(CmdSetEvent)(
VkCommandBuffer commandBuffer,
VkEvent event,
diff --git a/src/vulkan/gen8_cmd_buffer.c b/src/vulkan/gen8_cmd_buffer.c
index 1635a53b32a..ebd6123454d 100644
--- a/src/vulkan/gen8_cmd_buffer.c
+++ b/src/vulkan/gen8_cmd_buffer.c
@@ -603,179 +603,6 @@ genX(cmd_buffer_flush_compute_state)(struct anv_cmd_buffer *cmd_buffer)
}
static void
-cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
-{
- struct anv_device *device = cmd_buffer->device;
- const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
- const struct anv_image_view *iview =
- anv_cmd_buffer_get_depth_stencil_view(cmd_buffer);
- const struct anv_image *image = iview ? iview->image : NULL;
- const struct anv_format *anv_format =
- iview ? anv_format_for_vk_format(iview->vk_format) : NULL;
- const bool has_depth = iview && anv_format->has_depth;
- const bool has_stencil = iview && anv_format->has_stencil;
-
- /* FIXME: Implement the PMA stall W/A */
- /* FIXME: Width and Height are wrong */
-
- /* Emit 3DSTATE_DEPTH_BUFFER */
- if (has_depth) {
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DEPTH_BUFFER),
- .SurfaceType = SURFTYPE_2D,
- .DepthWriteEnable = true,
- .StencilWriteEnable = has_stencil,
- .HierarchicalDepthBufferEnable = false,
- .SurfaceFormat = isl_surf_get_depth_format(&device->isl_dev,
- &image->depth_surface.isl),
- .SurfacePitch = image->depth_surface.isl.row_pitch - 1,
- .SurfaceBaseAddress = {
- .bo = image->bo,
- .offset = image->depth_surface.offset,
- },
- .Height = fb->height - 1,
- .Width = fb->width - 1,
- .LOD = 0,
- .Depth = 1 - 1,
- .MinimumArrayElement = 0,
- .DepthBufferObjectControlState = GENX(MOCS),
- .RenderTargetViewExtent = 1 - 1,
- .SurfaceQPitch = isl_surf_get_array_pitch_el_rows(&image->depth_surface.isl) >> 2);
- } else {
- /* Even when no depth buffer is present, the hardware requires that
- * 3DSTATE_DEPTH_BUFFER be programmed correctly. The Broadwell PRM says:
- *
- * If a null depth buffer is bound, the driver must instead bind depth as:
- * 3DSTATE_DEPTH.SurfaceType = SURFTYPE_2D
- * 3DSTATE_DEPTH.Width = 1
- * 3DSTATE_DEPTH.Height = 1
- * 3DSTATE_DEPTH.SuraceFormat = D16_UNORM
- * 3DSTATE_DEPTH.SurfaceBaseAddress = 0
- * 3DSTATE_DEPTH.HierarchicalDepthBufferEnable = 0
- * 3DSTATE_WM_DEPTH_STENCIL.DepthTestEnable = 0
- * 3DSTATE_WM_DEPTH_STENCIL.DepthBufferWriteEnable = 0
- *
- * The PRM is wrong, though. The width and height must be programmed to
- * actual framebuffer's width and height, even when neither depth buffer
- * nor stencil buffer is present.
- */
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DEPTH_BUFFER),
- .SurfaceType = SURFTYPE_2D,
- .SurfaceFormat = D16_UNORM,
- .Width = fb->width - 1,
- .Height = fb->height - 1,
- .StencilWriteEnable = has_stencil);
- }
-
- /* Emit 3DSTATE_STENCIL_BUFFER */
- if (has_stencil) {
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_STENCIL_BUFFER),
- .StencilBufferEnable = true,
- .StencilBufferObjectControlState = GENX(MOCS),
-
- /* Stencil buffers have strange pitch. The PRM says:
- *
- * The pitch must be set to 2x the value computed based on width,
- * as the stencil buffer is stored with two rows interleaved.
- */
- .SurfacePitch = 2 * image->stencil_surface.isl.row_pitch - 1,
-
- .SurfaceBaseAddress = {
- .bo = image->bo,
- .offset = image->offset + image->stencil_surface.offset,
- },
- .SurfaceQPitch = isl_surf_get_array_pitch_el_rows(&image->stencil_surface.isl) >> 2);
- } else {
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_STENCIL_BUFFER));
- }
-
- /* Disable hierarchial depth buffers. */
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_HIER_DEPTH_BUFFER));
-
- /* Clear the clear params. */
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CLEAR_PARAMS));
-}
-
-/**
- * @see anv_cmd_buffer_set_subpass()
- */
-void
-genX(cmd_buffer_set_subpass)(struct anv_cmd_buffer *cmd_buffer,
- struct anv_subpass *subpass)
-{
- cmd_buffer->state.subpass = subpass;
-
- cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
-
- cmd_buffer_emit_depth_stencil(cmd_buffer);
-}
-
-void genX(CmdBeginRenderPass)(
- VkCommandBuffer commandBuffer,
- const VkRenderPassBeginInfo* pRenderPassBegin,
- VkSubpassContents contents)
-{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
- ANV_FROM_HANDLE(anv_render_pass, pass, pRenderPassBegin->renderPass);
- ANV_FROM_HANDLE(anv_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
-
- cmd_buffer->state.framebuffer = framebuffer;
- cmd_buffer->state.pass = pass;
- anv_cmd_state_setup_attachments(cmd_buffer, pRenderPassBegin);
-
- genX(flush_pipeline_select_3d)(cmd_buffer);
-
- const VkRect2D *render_area = &pRenderPassBegin->renderArea;
-
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DRAWING_RECTANGLE),
- .ClippedDrawingRectangleYMin = render_area->offset.y,
- .ClippedDrawingRectangleXMin = render_area->offset.x,
- .ClippedDrawingRectangleYMax =
- render_area->offset.y + render_area->extent.height - 1,
- .ClippedDrawingRectangleXMax =
- render_area->offset.x + render_area->extent.width - 1,
- .DrawingRectangleOriginY = 0,
- .DrawingRectangleOriginX = 0);
-
- genX(cmd_buffer_set_subpass)(cmd_buffer, pass->subpasses);
- anv_cmd_buffer_clear_subpass(cmd_buffer);
-}
-
-void genX(CmdNextSubpass)(
- VkCommandBuffer commandBuffer,
- VkSubpassContents contents)
-{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-
- assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
-
- anv_cmd_buffer_resolve_subpass(cmd_buffer);
- genX(cmd_buffer_set_subpass)(cmd_buffer, cmd_buffer->state.subpass + 1);
- anv_cmd_buffer_clear_subpass(cmd_buffer);
-}
-
-void genX(CmdEndRenderPass)(
- VkCommandBuffer commandBuffer)
-{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-
- anv_cmd_buffer_resolve_subpass(cmd_buffer);
-
- /* Emit a flushing pipe control at the end of a pass. This is kind of a
- * hack but it ensures that render targets always actually get written.
- * Eventually, we should do flushing based on image format transitions
- * or something of that nature.
- */
- anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL),
- .PostSyncOperation = NoWrite,
- .RenderTargetCacheFlushEnable = true,
- .InstructionCacheInvalidateEnable = true,
- .DepthCacheFlushEnable = true,
- .VFCacheInvalidationEnable = true,
- .TextureCacheInvalidationEnable = true,
- .CommandStreamerStallEnable = true);
-}
-
-static void
emit_ps_depth_count(struct anv_batch *batch,
struct anv_bo *bo, uint32_t offset)
{
diff --git a/src/vulkan/genX_cmd_buffer.c b/src/vulkan/genX_cmd_buffer.c
index 7c6ad43a9b2..e8b215e6377 100644
--- a/src/vulkan/genX_cmd_buffer.c
+++ b/src/vulkan/genX_cmd_buffer.c
@@ -548,3 +548,182 @@ genX(flush_pipeline_select_3d)(struct anv_cmd_buffer *cmd_buffer)
cmd_buffer->state.current_pipeline = _3D;
}
}
+
+static void
+cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
+{
+ struct anv_device *device = cmd_buffer->device;
+ const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
+ const struct anv_image_view *iview =
+ anv_cmd_buffer_get_depth_stencil_view(cmd_buffer);
+ const struct anv_image *image = iview ? iview->image : NULL;
+ const struct anv_format *anv_format =
+ iview ? anv_format_for_vk_format(iview->vk_format) : NULL;
+ const bool has_depth = iview && anv_format->has_depth;
+ const bool has_stencil = iview && anv_format->has_stencil;
+
+ /* FIXME: Implement the PMA stall W/A */
+ /* FIXME: Width and Height are wrong */
+
+ /* Emit 3DSTATE_DEPTH_BUFFER */
+ if (has_depth) {
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DEPTH_BUFFER),
+ .SurfaceType = SURFTYPE_2D,
+ .DepthWriteEnable = true,
+ .StencilWriteEnable = has_stencil,
+ .HierarchicalDepthBufferEnable = false,
+ .SurfaceFormat = isl_surf_get_depth_format(&device->isl_dev,
+ &image->depth_surface.isl),
+ .SurfacePitch = image->depth_surface.isl.row_pitch - 1,
+ .SurfaceBaseAddress = {
+ .bo = image->bo,
+ .offset = image->depth_surface.offset,
+ },
+ .Height = fb->height - 1,
+ .Width = fb->width - 1,
+ .LOD = 0,
+ .Depth = 1 - 1,
+ .MinimumArrayElement = 0,
+ .DepthBufferObjectControlState = GENX(MOCS),
+#if ANV_GEN >= 8
+ .SurfaceQPitch = isl_surf_get_array_pitch_el_rows(&image->depth_surface.isl) >> 2,
+#endif
+ .RenderTargetViewExtent = 1 - 1);
+ } else {
+ /* Even when no depth buffer is present, the hardware requires that
+ * 3DSTATE_DEPTH_BUFFER be programmed correctly. The Broadwell PRM says:
+ *
+ * If a null depth buffer is bound, the driver must instead bind depth as:
+ * 3DSTATE_DEPTH.SurfaceType = SURFTYPE_2D
+ * 3DSTATE_DEPTH.Width = 1
+ * 3DSTATE_DEPTH.Height = 1
+ * 3DSTATE_DEPTH.SuraceFormat = D16_UNORM
+ * 3DSTATE_DEPTH.SurfaceBaseAddress = 0
+ * 3DSTATE_DEPTH.HierarchicalDepthBufferEnable = 0
+ * 3DSTATE_WM_DEPTH_STENCIL.DepthTestEnable = 0
+ * 3DSTATE_WM_DEPTH_STENCIL.DepthBufferWriteEnable = 0
+ *
+ * The PRM is wrong, though. The width and height must be programmed to
+ * actual framebuffer's width and height, even when neither depth buffer
+ * nor stencil buffer is present.
+ */
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DEPTH_BUFFER),
+ .SurfaceType = SURFTYPE_2D,
+ .SurfaceFormat = D16_UNORM,
+ .Width = fb->width - 1,
+ .Height = fb->height - 1,
+ .StencilWriteEnable = has_stencil);
+ }
+
+ /* Emit 3DSTATE_STENCIL_BUFFER */
+ if (has_stencil) {
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_STENCIL_BUFFER),
+#if ANV_GEN >= 8 || ANV_IS_HASWELL
+ .StencilBufferEnable = true,
+#endif
+ .StencilBufferObjectControlState = GENX(MOCS),
+
+ /* Stencil buffers have strange pitch. The PRM says:
+ *
+ * The pitch must be set to 2x the value computed based on width,
+ * as the stencil buffer is stored with two rows interleaved.
+ */
+ .SurfacePitch = 2 * image->stencil_surface.isl.row_pitch - 1,
+
+#if ANV_GEN >= 8
+ .SurfaceQPitch = isl_surf_get_array_pitch_el_rows(&image->stencil_surface.isl) >> 2,
+#endif
+ .SurfaceBaseAddress = {
+ .bo = image->bo,
+ .offset = image->offset + image->stencil_surface.offset,
+ });
+ } else {
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_STENCIL_BUFFER));
+ }
+
+ /* Disable hierarchial depth buffers. */
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_HIER_DEPTH_BUFFER));
+
+ /* Clear the clear params. */
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CLEAR_PARAMS));
+}
+
+/**
+ * @see anv_cmd_buffer_set_subpass()
+ */
+void
+genX(cmd_buffer_set_subpass)(struct anv_cmd_buffer *cmd_buffer,
+ struct anv_subpass *subpass)
+{
+ cmd_buffer->state.subpass = subpass;
+
+ cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
+
+ cmd_buffer_emit_depth_stencil(cmd_buffer);
+}
+
+void genX(CmdBeginRenderPass)(
+ VkCommandBuffer commandBuffer,
+ const VkRenderPassBeginInfo* pRenderPassBegin,
+ VkSubpassContents contents)
+{
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+ ANV_FROM_HANDLE(anv_render_pass, pass, pRenderPassBegin->renderPass);
+ ANV_FROM_HANDLE(anv_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
+
+ cmd_buffer->state.framebuffer = framebuffer;
+ cmd_buffer->state.pass = pass;
+ anv_cmd_state_setup_attachments(cmd_buffer, pRenderPassBegin);
+
+ genX(flush_pipeline_select_3d)(cmd_buffer);
+
+ const VkRect2D *render_area = &pRenderPassBegin->renderArea;
+
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DRAWING_RECTANGLE),
+ .ClippedDrawingRectangleYMin = render_area->offset.y,
+ .ClippedDrawingRectangleXMin = render_area->offset.x,
+ .ClippedDrawingRectangleYMax =
+ render_area->offset.y + render_area->extent.height - 1,
+ .ClippedDrawingRectangleXMax =
+ render_area->offset.x + render_area->extent.width - 1,
+ .DrawingRectangleOriginY = 0,
+ .DrawingRectangleOriginX = 0);
+
+ genX(cmd_buffer_set_subpass)(cmd_buffer, pass->subpasses);
+ anv_cmd_buffer_clear_subpass(cmd_buffer);
+}
+
+void genX(CmdNextSubpass)(
+ VkCommandBuffer commandBuffer,
+ VkSubpassContents contents)
+{
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+
+ assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+
+ anv_cmd_buffer_resolve_subpass(cmd_buffer);
+ genX(cmd_buffer_set_subpass)(cmd_buffer, cmd_buffer->state.subpass + 1);
+ anv_cmd_buffer_clear_subpass(cmd_buffer);
+}
+
+void genX(CmdEndRenderPass)(
+ VkCommandBuffer commandBuffer)
+{
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+
+ anv_cmd_buffer_resolve_subpass(cmd_buffer);
+
+ /* Emit a flushing pipe control at the end of a pass. This is kind of a
+ * hack but it ensures that render targets always actually get written.
+ * Eventually, we should do flushing based on image format transitions
+ * or something of that nature.
+ */
+ anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL),
+ .PostSyncOperation = NoWrite,
+ .RenderTargetCacheFlushEnable = true,
+ .InstructionCacheInvalidateEnable = true,
+ .DepthCacheFlushEnable = true,
+ .VFCacheInvalidationEnable = true,
+ .TextureCacheInvalidationEnable = true,
+ .CommandStreamerStallEnable = true);
+}