mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 18:18:06 +02:00
anv: Deduplicate render pass code
This lets us share the renderpass code and depth/stencil state code between gen 7 and gen 8.
This commit is contained in:
parent
ac4fd0ed21
commit
85f67cf16e
3 changed files with 179 additions and 343 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -602,179 +602,6 @@ genX(cmd_buffer_flush_compute_state)(struct anv_cmd_buffer *cmd_buffer)
|
|||
cmd_buffer->state.compute_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;
|
||||
|
||||
/* 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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue