From b29ea49e8e392155da40338b4dc631539c89af53 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 19 Apr 2017 10:34:37 +1000 Subject: [PATCH] radv/meta: move clear color to using push constants The color clear value is uniform and needs only to be emitted from the frag shader, so just push it down via a push constant, and remove the vertex buffer completely. The depth clear value needs to be emitted from the vertex shader, but is only a single value. Reviewed-by: Bas Nieuwenhuizen Signed-off-by: Dave Airlie --- src/amd/vulkan/radv_meta_clear.c | 206 ++++++++++++------------------- src/amd/vulkan/radv_private.h | 2 + 2 files changed, 78 insertions(+), 130 deletions(-) diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c index 2fa50cf0b5d..adabc1b9212 100644 --- a/src/amd/vulkan/radv_meta_clear.c +++ b/src/amd/vulkan/radv_meta_clear.c @@ -28,16 +28,6 @@ #include "util/format_rgb9e5.h" #include "vk_format.h" -/** Vertex attributes for color clears. */ -struct color_clear_vattrs { - VkClearColorValue color; -}; - -/** Vertex attributes for depthstencil clears. */ -struct depthstencil_clear_vattrs { - float depth_clear; -}; - enum { DEPTH_CLEAR_SLOW, DEPTH_CLEAR_FAST_EXPCLEAR, @@ -66,33 +56,23 @@ build_color_shaders(struct nir_shader **out_vs, "gl_Position"); vs_out_pos->data.location = VARYING_SLOT_POS; - nir_variable *vs_in_color = - nir_variable_create(vs_b.shader, nir_var_shader_in, color_type, - "a_color"); - vs_in_color->data.location = VERT_ATTRIB_GENERIC0; - - nir_variable *vs_out_color = - nir_variable_create(vs_b.shader, nir_var_shader_out, color_type, - "v_color"); - vs_out_color->data.location = VARYING_SLOT_VAR0; - vs_out_color->data.interpolation = INTERP_MODE_FLAT; - - nir_variable *fs_in_color = - nir_variable_create(fs_b.shader, nir_var_shader_in, color_type, - "v_color"); - fs_in_color->data.location = vs_out_color->data.location; - fs_in_color->data.interpolation = vs_out_color->data.interpolation; + nir_intrinsic_instr *in_color_load = nir_intrinsic_instr_create(fs_b.shader, nir_intrinsic_load_push_constant); + nir_intrinsic_set_base(in_color_load, 0); + nir_intrinsic_set_range(in_color_load, 16); + in_color_load->src[0] = nir_src_for_ssa(nir_imm_int(&fs_b, 0)); + in_color_load->num_components = 4; + nir_ssa_dest_init(&in_color_load->instr, &in_color_load->dest, 4, 32, "clear color"); + nir_builder_instr_insert(&fs_b, &in_color_load->instr); nir_variable *fs_out_color = nir_variable_create(fs_b.shader, nir_var_shader_out, color_type, "f_color"); fs_out_color->data.location = FRAG_RESULT_DATA0 + frag_output; - nir_ssa_def *outvec = radv_meta_gen_rect_vertices(&vs_b); + nir_store_var(&fs_b, fs_out_color, &in_color_load->dest.ssa, 0xf); + nir_ssa_def *outvec = radv_meta_gen_rect_vertices(&vs_b); nir_store_var(&vs_b, vs_out_pos, outvec, 0xf); - nir_copy_var(&vs_b, vs_out_color, vs_in_color); - nir_copy_var(&fs_b, fs_out_color, fs_in_color); const struct glsl_type *layer_type = glsl_int_type(); nir_variable *vs_out_layer = @@ -117,6 +97,7 @@ create_pipeline(struct radv_device *device, const VkPipelineVertexInputStateCreateInfo *vi_state, const VkPipelineDepthStencilStateCreateInfo *ds_state, const VkPipelineColorBlendStateCreateInfo *cb_state, + const VkPipelineLayout layout, const struct radv_graphics_pipeline_create_info *extra, const VkAllocationCallbacks *alloc, struct radv_pipeline **pipeline) @@ -196,10 +177,11 @@ create_pipeline(struct radv_device *device, VK_DYNAMIC_STATE_STENCIL_REFERENCE, }, }, - .flags = 0, - .renderPass = radv_render_pass_to_handle(render_pass), - .subpass = 0, - }, + .layout = layout, + .flags = 0, + .renderPass = radv_render_pass_to_handle(render_pass), + .subpass = 0, + }, extra, alloc, &pipeline_h); @@ -265,24 +247,8 @@ create_color_pipeline(struct radv_device *device, const VkPipelineVertexInputStateCreateInfo vi_state = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 1, - .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) { - { - .binding = 0, - .stride = sizeof(struct color_clear_vattrs), - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX - }, - }, - .vertexAttributeDescriptionCount = 1, - .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) { - { - /* Color */ - .location = 0, - .binding = 0, - .format = VK_FORMAT_R32G32B32A32_SFLOAT, - .offset = 0, - }, - }, + .vertexBindingDescriptionCount = 0, + .vertexAttributeDescriptionCount = 0, }; const VkPipelineDepthStencilStateCreateInfo ds_state = { @@ -315,6 +281,7 @@ create_color_pipeline(struct radv_device *device, }; result = create_pipeline(device, radv_render_pass_from_handle(pass), samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state, + device->meta_state.clear_color_p_layout, &extra, &device->meta_state.alloc, pipeline); return result; @@ -357,7 +324,12 @@ radv_device_finish_meta_clear_state(struct radv_device *device) } destroy_render_pass(device, state->clear[i].depthstencil_rp); } - + radv_DestroyPipelineLayout(radv_device_to_handle(device), + state->clear_color_p_layout, + &state->alloc); + radv_DestroyPipelineLayout(radv_device_to_handle(device), + state->clear_depth_p_layout, + &state->alloc); } static void @@ -378,7 +350,6 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer, VkClearColorValue clear_value = clear_att->clearValue.color; VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); VkPipeline pipeline_h; - uint32_t offset; if (fs_key == -1) { radv_finishme("color clears incomplete"); @@ -396,17 +367,10 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer, assert(clear_att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); assert(clear_att->colorAttachment < subpass->color_count); - const struct color_clear_vattrs vertex_data[3] = { - { - .color = clear_value, - }, - { - .color = clear_value, - }, - { - .color = clear_value, - }, - }; + radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), + device->meta_state.clear_color_p_layout, + VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, + &clear_value); struct radv_subpass clear_subpass = { .color_count = 1, @@ -418,19 +382,6 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer, radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass, false); - radv_cmd_buffer_upload_data(cmd_buffer, sizeof(vertex_data), 16, vertex_data, &offset); - struct radv_buffer vertex_buffer = { - .device = device, - .size = sizeof(vertex_data), - .bo = cmd_buffer->upload.upload_bo, - .offset = offset, - }; - - - radv_CmdBindVertexBuffers(cmd_buffer_h, 0, 1, - (VkBuffer[]) { radv_buffer_to_handle(&vertex_buffer) }, - (VkDeviceSize[]) { 0 }); - if (cmd_buffer->state.pipeline != pipeline) { radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_h); @@ -464,19 +415,21 @@ build_depthstencil_shader(struct nir_shader **out_vs, struct nir_shader **out_fs vs_b.shader->info->name = ralloc_strdup(vs_b.shader, "meta_clear_depthstencil_vs"); fs_b.shader->info->name = ralloc_strdup(fs_b.shader, "meta_clear_depthstencil_fs"); const struct glsl_type *position_out_type = glsl_vec4_type(); - const struct glsl_type *position_type = glsl_float_type(); - - nir_variable *vs_in_pos = - nir_variable_create(vs_b.shader, nir_var_shader_in, position_type, - "a_position"); - vs_in_pos->data.location = VERT_ATTRIB_GENERIC0; nir_variable *vs_out_pos = nir_variable_create(vs_b.shader, nir_var_shader_out, position_out_type, "gl_Position"); vs_out_pos->data.location = VARYING_SLOT_POS; - nir_ssa_def *outvec = radv_meta_gen_rect_vertices_comp2(&vs_b, nir_load_var(&vs_b, vs_in_pos)); + nir_intrinsic_instr *in_color_load = nir_intrinsic_instr_create(vs_b.shader, nir_intrinsic_load_push_constant); + nir_intrinsic_set_base(in_color_load, 0); + nir_intrinsic_set_range(in_color_load, 4); + in_color_load->src[0] = nir_src_for_ssa(nir_imm_int(&vs_b, 0)); + in_color_load->num_components = 1; + nir_ssa_dest_init(&in_color_load->instr, &in_color_load->dest, 1, 32, "depth value"); + nir_builder_instr_insert(&vs_b, &in_color_load->instr); + + nir_ssa_def *outvec = radv_meta_gen_rect_vertices_comp2(&vs_b, &in_color_load->dest.ssa); nir_store_var(&vs_b, vs_out_pos, outvec, 0xf); const struct glsl_type *layer_type = glsl_int_type(); @@ -541,24 +494,8 @@ create_depthstencil_pipeline(struct radv_device *device, const VkPipelineVertexInputStateCreateInfo vi_state = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 1, - .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) { - { - .binding = 0, - .stride = sizeof(struct depthstencil_clear_vattrs), - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX - }, - }, - .vertexAttributeDescriptionCount = 1, - .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) { - { - /* Position */ - .location = 0, - .binding = 0, - .format = VK_FORMAT_R32_SFLOAT, - .offset = 0, - }, - }, + .vertexBindingDescriptionCount = 0, + .vertexAttributeDescriptionCount = 0, }; const VkPipelineDepthStencilStateCreateInfo ds_state = { @@ -598,6 +535,7 @@ create_depthstencil_pipeline(struct radv_device *device, } result = create_pipeline(device, radv_render_pass_from_handle(render_pass), samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state, + device->meta_state.clear_depth_p_layout, &extra, &device->meta_state.alloc, pipeline); return result; } @@ -664,7 +602,6 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, const uint32_t samples = iview->image->info.samples; const uint32_t samples_log2 = ffs(samples) - 1; VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); - uint32_t offset; assert(aspects == VK_IMAGE_ASPECT_DEPTH_BIT || aspects == VK_IMAGE_ASPECT_STENCIL_BIT || @@ -675,35 +612,16 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, if (!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) clear_value.depth = 1.0f; - const struct depthstencil_clear_vattrs vertex_data[3] = { - { - .depth_clear = clear_value.depth, - }, - { - .depth_clear = clear_value.depth, - }, - { - .depth_clear = clear_value.depth, - }, - }; - - radv_cmd_buffer_upload_data(cmd_buffer, sizeof(vertex_data), 16, vertex_data, &offset); - struct radv_buffer vertex_buffer = { - .device = device, - .size = sizeof(vertex_data), - .bo = cmd_buffer->upload.upload_bo, - .offset = offset, - }; + radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), + device->meta_state.clear_depth_p_layout, + VK_SHADER_STAGE_VERTEX_BIT, 0, 4, + &clear_value.depth); if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT, clear_value.stencil); } - radv_CmdBindVertexBuffers(cmd_buffer_h, 0, 1, - (VkBuffer[]) { radv_buffer_to_handle(&vertex_buffer) }, - (VkDeviceSize[]) { 0 }); - struct radv_pipeline *pipeline = pick_depthstencil_pipeline(meta_state, iview, samples_log2, @@ -755,6 +673,34 @@ radv_device_init_meta_clear_state(struct radv_device *device) memset(&device->meta_state.clear, 0, sizeof(device->meta_state.clear)); + VkPipelineLayoutCreateInfo pl_color_create_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .setLayoutCount = 0, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16}, + }; + + res = radv_CreatePipelineLayout(radv_device_to_handle(device), + &pl_color_create_info, + &device->meta_state.alloc, + &device->meta_state.clear_color_p_layout); + if (res != VK_SUCCESS) + goto fail; + + VkPipelineLayoutCreateInfo pl_depth_create_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .setLayoutCount = 0, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, + }; + + res = radv_CreatePipelineLayout(radv_device_to_handle(device), + &pl_depth_create_info, + &device->meta_state.alloc, + &device->meta_state.clear_depth_p_layout); + if (res != VK_SUCCESS) + goto fail; + for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) { uint32_t samples = 1 << i; for (uint32_t j = 0; j < ARRAY_SIZE(pipeline_formats); ++j) { @@ -975,7 +921,7 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer) if (!subpass_needs_clear(cmd_buffer)) return; - radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer); + radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state, cmd_buffer); VkClearRect clear_rect = { .rect = cmd_state->render_area, @@ -1223,7 +1169,7 @@ void radv_CmdClearColorImage( if (cs) radv_meta_begin_cleari(cmd_buffer, &saved_state.compute); else - radv_meta_save_graphics_reset_vport_scissor(&saved_state.gfx, cmd_buffer); + radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state.gfx, cmd_buffer); radv_cmd_clear_image(cmd_buffer, image, imageLayout, (const VkClearValue *) pColor, @@ -1247,7 +1193,7 @@ void radv_CmdClearDepthStencilImage( RADV_FROM_HANDLE(radv_image, image, image_h); struct radv_meta_saved_state saved_state; - radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer); + radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state, cmd_buffer); radv_cmd_clear_image(cmd_buffer, image, imageLayout, (const VkClearValue *) pDepthStencil, @@ -1271,7 +1217,7 @@ void radv_CmdClearAttachments( if (!cmd_buffer->state.subpass) return; - radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer); + radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state, cmd_buffer); /* FINISHME: We can do better than this dumb loop. It thrashes too much * state. diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 1e023560945..088d24a7066 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -343,6 +343,8 @@ struct radv_meta_state { struct radv_pipeline *depthstencil_pipeline[NUM_DEPTH_CLEAR_PIPELINES]; } clear[1 + MAX_SAMPLES_LOG2]; + VkPipelineLayout clear_color_p_layout; + VkPipelineLayout clear_depth_p_layout; struct { VkRenderPass render_pass[NUM_META_FS_KEYS]; -- 2.30.2