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=499b3ae27af5031f7bb1470568a0ee68aa107950;hpb=ab0e625a671d19bb6a736d663bbc6fa5fd9ecd06;p=mesa.git diff --git a/src/amd/vulkan/radv_meta_resolve_fs.c b/src/amd/vulkan/radv_meta_resolve_fs.c index 499b3ae27af..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, @@ -458,9 +460,17 @@ void radv_meta_resolve_fragment_image(struct radv_cmd_buffer *cmd_buffer, unsigned dst_layout = radv_meta_dst_layout_from_layout(dest_image_layout); VkRenderPass rp; - radv_decompress_resolve_src(cmd_buffer, src_image, + 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, @@ -580,39 +590,25 @@ radv_cmd_buffer_resolve_subpass_fs(struct radv_cmd_buffer *cmd_buffer) struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; const struct radv_subpass *subpass = cmd_buffer->state.subpass; 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. - */ + /* 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; + barrier.dst_access_mask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; + radv_subpass_barrier(cmd_buffer, &barrier); - if (!subpass->has_resolve) - return; + 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); - /* Resolves happen before the end-of-subpass barriers get executed, - * so we have to make the attachment shader-readable */ - cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_PS_PARTIAL_FLUSH | - RADV_CMD_FLAG_FLUSH_AND_INV_CB | - RADV_CMD_FLAG_FLUSH_AND_INV_CB_META | - RADV_CMD_FLAG_FLUSH_AND_INV_DB | - RADV_CMD_FLAG_FLUSH_AND_INV_DB_META | - RADV_CMD_FLAG_INV_GLOBAL_L2 | - RADV_CMD_FLAG_INV_VMEM_L1; - - radv_decompress_resolve_subpass_src(cmd_buffer); - for (uint32_t i = 0; i < subpass->color_count; ++i) { - VkAttachmentReference src_att = subpass->color_attachments[i]; - VkAttachmentReference dest_att = subpass->resolve_attachments[i]; + struct radv_subpass_attachment src_att = subpass->color_attachments[i]; + struct radv_subpass_attachment dest_att = subpass->resolve_attachments[i]; if (src_att.attachment == VK_ATTACHMENT_UNUSED || dest_att.attachment == VK_ATTACHMENT_UNUSED) @@ -623,7 +619,7 @@ radv_cmd_buffer_resolve_subpass_fs(struct radv_cmd_buffer *cmd_buffer) struct radv_subpass resolve_subpass = { .color_count = 1, - .color_attachments = (VkAttachmentReference[]) { dest_att }, + .color_attachments = (struct radv_subpass_attachment[]) { dest_att }, .depth_stencil_attachment = { .attachment = VK_ATTACHMENT_UNUSED }, };