From 16119ad884f472ed8e59811fca60bccc1dd8580a Mon Sep 17 00:00:00 2001 From: Chad Versace Date: Wed, 4 Nov 2015 17:00:01 -0800 Subject: [PATCH] anv/meta: Finish load clears for stencil attachments Tested by Crucible "func.depthstencil.stencil_triangles.*" in commit c194292d5eadb84e9d7489fc01ce0b653cdd4ca5 (HEAD -> master) Author: Chad Versace Date: Wed Nov 4 16:19:24 2015 -0800 Subject: func.depthstencil: Remove stencil clear workaround for Mesa --- src/vulkan/anv_meta_clear.c | 114 +++++++++++++++++++++++++++--------- src/vulkan/anv_private.h | 4 +- 2 files changed, 88 insertions(+), 30 deletions(-) diff --git a/src/vulkan/anv_meta_clear.c b/src/vulkan/anv_meta_clear.c index 04640c04b7b..7eb4c5587cc 100644 --- a/src/vulkan/anv_meta_clear.c +++ b/src/vulkan/anv_meta_clear.c @@ -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); } } diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h index 396d4138dc1..858063da45c 100644 --- a/src/vulkan/anv_private.h +++ b/src/vulkan/anv_private.h @@ -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 { -- 2.30.2