X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_meta_resolve_fs.c;h=af4a6fe7a66be032d806d0c8af96f3eb6092f11a;hb=90819abb56f6b1a0cd4946b13b6caf24fb46e500;hp=0e4957b163cbeccb7d2add7de1503e004d4e9a63;hpb=0a8127bbfbe8a8af45dacf6c0998a8f0f1152f4b;p=mesa.git diff --git a/src/amd/vulkan/radv_meta_resolve_fs.c b/src/amd/vulkan/radv_meta_resolve_fs.c index 0e4957b163c..af4a6fe7a66 100644 --- a/src/amd/vulkan/radv_meta_resolve_fs.c +++ b/src/amd/vulkan/radv_meta_resolve_fs.c @@ -156,30 +156,23 @@ static const VkPipelineVertexInputStateCreateInfo normal_vi_create_info = { .vertexAttributeDescriptionCount = 0, }; -static VkFormat pipeline_formats[] = { - VK_FORMAT_R8G8B8A8_UNORM, - VK_FORMAT_R8G8B8A8_UINT, - VK_FORMAT_R8G8B8A8_SINT, - VK_FORMAT_A2R10G10B10_UINT_PACK32, - VK_FORMAT_A2R10G10B10_SINT_PACK32, - VK_FORMAT_R16G16B16A16_UNORM, - VK_FORMAT_R16G16B16A16_SNORM, - VK_FORMAT_R16G16B16A16_UINT, - VK_FORMAT_R16G16B16A16_SINT, - VK_FORMAT_R32_SFLOAT, - VK_FORMAT_R32G32_SFLOAT, - VK_FORMAT_R32G32B32A32_SFLOAT -}; - static VkResult create_resolve_pipeline(struct radv_device *device, int samples_log2, VkFormat format) { + mtx_lock(&device->meta_state.mtx); + + unsigned fs_key = radv_format_meta_fs_key(format); + VkPipeline *pipeline = &device->meta_state.resolve_fragment.rc[samples_log2].pipeline[fs_key]; + if (*pipeline) { + mtx_unlock(&device->meta_state.mtx); + return VK_SUCCESS; + } + VkResult result; bool is_integer = false; uint32_t samples = 1 << samples_log2; - unsigned fs_key = radv_format_meta_fs_key(format); const VkPipelineVertexInputStateCreateInfo *vi_create_info; vi_create_info = &normal_vi_create_info; if (vk_format_is_int(format)) @@ -195,9 +188,6 @@ create_resolve_pipeline(struct radv_device *device, assert(!*rp); - VkPipeline *pipeline = &device->meta_state.resolve_fragment.rc[samples_log2].pipeline[fs_key]; - assert(!*pipeline); - VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = { { .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, @@ -322,11 +312,12 @@ create_resolve_pipeline(struct radv_device *device, ralloc_free(vs.nir); ralloc_free(fs.nir); + mtx_unlock(&device->meta_state.mtx); return result; } VkResult -radv_device_init_meta_resolve_fragment_state(struct radv_device *device) +radv_device_init_meta_resolve_fragment_state(struct radv_device *device, bool on_demand) { VkResult res; @@ -334,9 +325,12 @@ radv_device_init_meta_resolve_fragment_state(struct radv_device *device) if (res != VK_SUCCESS) goto fail; + if (on_demand) + return VK_SUCCESS; + for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) { - for (unsigned j = 0; j < ARRAY_SIZE(pipeline_formats); ++j) { - res = create_resolve_pipeline(device, i, pipeline_formats[j]); + for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) { + res = create_resolve_pipeline(device, i, radv_fs_key_format_exemplars[j]); if (res != VK_SUCCESS) goto fail; } @@ -419,10 +413,18 @@ emit_resolve(struct radv_cmd_buffer *cmd_buffer, push_constants); unsigned fs_key = radv_format_meta_fs_key(dest_iview->vk_format); - VkPipeline pipeline_h = device->meta_state.resolve_fragment.rc[samples_log2].pipeline[fs_key]; + VkPipeline* pipeline = &device->meta_state.resolve_fragment.rc[samples_log2].pipeline[fs_key]; + + if (*pipeline == VK_NULL_HANDLE) { + VkResult ret = create_resolve_pipeline(device, samples_log2, radv_fs_key_format_exemplars[fs_key]); + if (ret != VK_SUCCESS) { + cmd_buffer->record_result = ret; + return; + } + } radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline_h); + *pipeline); radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) { .x = dest_offset->x, @@ -461,6 +463,14 @@ void radv_meta_resolve_fragment_image(struct radv_cmd_buffer *cmd_buffer, radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout, region_count, regions); + if (!device->meta_state.resolve_fragment.rc[samples_log2].render_pass[fs_key][dst_layout]) { + VkResult ret = create_resolve_pipeline(device, samples_log2, radv_fs_key_format_exemplars[fs_key]); + if (ret != VK_SUCCESS) { + cmd_buffer->record_result = ret; + return; + } + } + rp = device->meta_state.resolve_fragment.rc[samples_log2].render_pass[fs_key][dst_layout]; radv_meta_save(&saved_state, cmd_buffer, @@ -582,33 +592,20 @@ radv_cmd_buffer_resolve_subpass_fs(struct radv_cmd_buffer *cmd_buffer) struct radv_meta_saved_state saved_state; struct radv_subpass_barrier barrier; - /* FINISHME(perf): Skip clears for resolve attachments. - * - * From the Vulkan 1.0 spec: - * - * If the first use of an attachment in a render pass is as a resolve - * attachment, then the loadOp is effectively ignored as the resolve is - * guaranteed to overwrite all pixels in the render area. - */ - - if (!subpass->has_resolve) - return; - - radv_meta_save(&saved_state, cmd_buffer, - RADV_META_SAVE_GRAPHICS_PIPELINE | - RADV_META_SAVE_CONSTANTS | - RADV_META_SAVE_DESCRIPTORS); - /* Resolves happen before the end-of-subpass barriers get executed, * so we have to make the attachment shader-readable */ barrier.src_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - barrier.src_access_mask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + barrier.src_access_mask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; barrier.dst_access_mask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; radv_subpass_barrier(cmd_buffer, &barrier); radv_decompress_resolve_subpass_src(cmd_buffer); + radv_meta_save(&saved_state, cmd_buffer, + RADV_META_SAVE_GRAPHICS_PIPELINE | + RADV_META_SAVE_CONSTANTS | + RADV_META_SAVE_DESCRIPTORS); + for (uint32_t i = 0; i < subpass->color_count; ++i) { struct radv_subpass_attachment src_att = subpass->color_attachments[i]; struct radv_subpass_attachment dest_att = subpass->resolve_attachments[i];