anv/meta: Finish load clears for stencil attachments

Tested by Crucible "func.depthstencil.stencil_triangles.*" in

  commit c194292d5eadb84e9d7489fc01ce0b653cdd4ca5 (HEAD -> master)
  Author: Chad Versace <chad.versace@intel.com>
  Date:   Wed Nov 4 16:19:24 2015 -0800
  Subject: func.depthstencil: Remove stencil clear workaround for Mesa
This commit is contained in:
Chad Versace
2015-11-04 17:00:01 -08:00
parent a40f682c71
commit 16119ad884
2 changed files with 88 additions and 30 deletions
+85 -29
View File
@@ -33,8 +33,8 @@ struct color_clear_vattrs {
VkClearColorValue color;
};
/** Vertex attributes for depth clears. */
struct depth_clear_vattrs {
/** Vertex attributes for depthstencil clears. */
struct depthstencil_clear_vattrs {
struct anv_vue_header vue_header;
float position[2]; /*<< 3DPRIM_RECTLIST */
};
@@ -45,7 +45,8 @@ meta_clear_begin(struct anv_meta_saved_state *saved_state,
{
anv_meta_save(saved_state, cmd_buffer,
(1 << VK_DYNAMIC_STATE_VIEWPORT) |
(1 << VK_DYNAMIC_STATE_SCISSOR));
(1 << VK_DYNAMIC_STATE_SCISSOR) |
(1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE));
cmd_buffer->state.dynamic.viewport.count = 0;
cmd_buffer->state.dynamic.scissor.count = 0;
@@ -412,11 +413,13 @@ build_depthstencil_shaders(struct nir_shader **out_vs,
*out_fs = fs_b.shader;
}
static void
init_depth_pipeline(struct anv_device *device)
static struct anv_pipeline *
create_depthstencil_pipeline(struct anv_device *device,
VkImageAspectFlags aspects)
{
struct nir_shader *vs_nir;
struct nir_shader *fs_nir;
build_depthstencil_shaders(&vs_nir, &fs_nir);
const VkPipelineVertexInputStateCreateInfo vi_state = {
@@ -425,7 +428,7 @@ init_depth_pipeline(struct anv_device *device)
.pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
{
.binding = 0,
.strideInBytes = sizeof(struct depth_clear_vattrs),
.strideInBytes = sizeof(struct depthstencil_clear_vattrs),
.stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
},
},
@@ -436,25 +439,32 @@ init_depth_pipeline(struct anv_device *device)
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_UINT,
.offsetInBytes = offsetof(struct depth_clear_vattrs, vue_header),
.offsetInBytes = offsetof(struct depthstencil_clear_vattrs, vue_header),
},
{
/* Position */
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offsetInBytes = offsetof(struct depth_clear_vattrs, position),
.offsetInBytes = offsetof(struct depthstencil_clear_vattrs, position),
},
},
};
const VkPipelineDepthStencilStateCreateInfo ds_state = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
.depthTestEnable = true,
.depthTestEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
.depthCompareOp = VK_COMPARE_OP_ALWAYS,
.depthWriteEnable = true,
.depthWriteEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
.depthBoundsTestEnable = false,
.stencilTestEnable = false,
.stencilTestEnable = (aspects & VK_IMAGE_ASPECT_STENCIL_BIT),
.front = {
.stencilPassOp = VK_STENCIL_OP_REPLACE,
.stencilCompareOp = VK_COMPARE_OP_ALWAYS,
.stencilWriteMask = UINT32_MAX,
.stencilReference = 0, /* dynamic */
},
.back = { 0 /* dont care */ },
};
const VkPipelineColorBlendStateCreateInfo cb_state = {
@@ -466,20 +476,21 @@ init_depth_pipeline(struct anv_device *device)
.pAttachments = NULL,
};
device->meta_state.clear.depth_pipeline =
create_pipeline(device, vs_nir, fs_nir, &vi_state, &ds_state,
&cb_state);
return create_pipeline(device, vs_nir, fs_nir, &vi_state, &ds_state,
&cb_state);
}
static void
emit_load_depth_clear(struct anv_cmd_buffer *cmd_buffer,
uint32_t attachment, float clear_value)
emit_load_depthstencil_clear(struct anv_cmd_buffer *cmd_buffer,
uint32_t attachment,
VkImageAspectFlags aspects,
VkClearDepthStencilValue clear_value)
{
struct anv_device *device = cmd_buffer->device;
VkCmdBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
const struct depth_clear_vattrs vertex_data[3] = {
const struct depthstencil_clear_vattrs vertex_data[3] = {
{
.vue_header = { 0 },
.position = { 0.0, 0.0 },
@@ -518,8 +529,10 @@ emit_load_depth_clear(struct anv_cmd_buffer *cmd_buffer,
.originY = 0,
.width = fb->width,
.height = fb->height,
.minDepth = clear_value,
.maxDepth = clear_value,
/* Ignored when clearing only stencil. */
.minDepth = clear_value.depth,
.maxDepth = clear_value.depth,
},
});
@@ -531,34 +544,72 @@ emit_load_depth_clear(struct anv_cmd_buffer *cmd_buffer,
}
});
if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
ANV_CALL(CmdSetStencilReference)(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
clear_value.stencil);
}
ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
(VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
(VkDeviceSize[]) { 0 });
if (cmd_buffer->state.pipeline != device->meta_state.clear.depth_pipeline) {
VkPipeline pipeline_h =
anv_pipeline_to_handle(device->meta_state.clear.depth_pipeline);
struct anv_pipeline *pipeline;
switch (aspects) {
case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
pipeline = device->meta_state.clear.depthstencil_pipeline;
break;
case VK_IMAGE_ASPECT_DEPTH_BIT:
pipeline = device->meta_state.clear.depth_only_pipeline;
break;
case VK_IMAGE_ASPECT_STENCIL_BIT:
pipeline = device->meta_state.clear.stencil_only_pipeline;
break;
default:
unreachable("expected depth or stencil aspect");
}
if (cmd_buffer->state.pipeline != pipeline) {
ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline_h);
anv_pipeline_to_handle(pipeline));
}
ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
}
static void
init_depthstencil_pipelines(struct anv_device *device)
{
device->meta_state.clear.depth_only_pipeline =
create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT);
device->meta_state.clear.stencil_only_pipeline =
create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT);
device->meta_state.clear.depthstencil_pipeline =
create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT |
VK_IMAGE_ASPECT_STENCIL_BIT);
}
void
anv_device_init_meta_clear_state(struct anv_device *device)
{
init_color_pipeline(device);
init_depth_pipeline(device);
init_depthstencil_pipelines(device);
}
void
anv_device_finish_meta_clear_state(struct anv_device *device)
{
ANV_CALL(DestroyPipeline)(anv_device_to_handle(device),
VkDevice device_h = anv_device_to_handle(device);
ANV_CALL(DestroyPipeline)(device_h,
anv_pipeline_to_handle(device->meta_state.clear.color_pipeline));
ANV_CALL(DestroyPipeline)(anv_device_to_handle(device),
anv_pipeline_to_handle(device->meta_state.clear.depth_pipeline));
ANV_CALL(DestroyPipeline)(device_h,
anv_pipeline_to_handle(device->meta_state.clear.depth_only_pipeline));
ANV_CALL(DestroyPipeline)(device_h,
anv_pipeline_to_handle(device->meta_state.clear.stencil_only_pipeline));
ANV_CALL(DestroyPipeline)(device_h,
anv_pipeline_to_handle(device->meta_state.clear.depthstencil_pipeline));
}
void
@@ -578,15 +629,20 @@ anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
emit_load_color_clear(cmd_buffer, a, clear_values[a].color);
}
} else {
VkImageAspectFlags aspects = 0;
if (att->format->depth_format &&
att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
emit_load_depth_clear(cmd_buffer, a, clear_values[a].depthStencil.depth);
aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
}
if (att->format->has_stencil &&
att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
anv_finishme("stencil load clear");
aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
}
emit_load_depthstencil_clear(cmd_buffer, a, aspects,
clear_values[a].depthStencil);
}
}
+3 -1
View File
@@ -449,7 +449,9 @@ void anv_finish_wsi(struct anv_instance *instance);
struct anv_meta_state {
struct {
struct anv_pipeline *color_pipeline;
struct anv_pipeline *depth_pipeline;
struct anv_pipeline *depth_only_pipeline;
struct anv_pipeline *stencil_only_pipeline;
struct anv_pipeline *depthstencil_pipeline;
} clear;
struct {