X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_meta_resolve_fs.c;h=d059760edf1034c3e9fd50ad32640c45c7937d81;hb=6880b42cfc1a1b2f30ccd02df1956a78efbe5551;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..d059760edf1 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, @@ -242,8 +232,8 @@ create_resolve_pipeline(struct radv_device *device, .attachment = VK_ATTACHMENT_UNUSED, .layout = VK_IMAGE_LAYOUT_GENERAL, }, - .preserveAttachmentCount = 1, - .pPreserveAttachments = (uint32_t[]) { 0 }, + .preserveAttachmentCount = 0, + .pPreserveAttachments = NULL, }, .dependencyCount = 0, }, &device->meta_state.alloc, rp + dst_layout); @@ -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; } @@ -373,6 +367,32 @@ radv_device_finish_meta_resolve_fragment_state(struct radv_device *device) &state->alloc); } +static VkPipeline * +radv_get_resolve_pipeline(struct radv_cmd_buffer *cmd_buffer, + struct radv_image_view *src_iview, + struct radv_image_view *dst_iview) +{ + struct radv_device *device = cmd_buffer->device; + unsigned fs_key = radv_format_meta_fs_key(dst_iview->vk_format); + const uint32_t samples = src_iview->image->info.samples; + const uint32_t samples_log2 = ffs(samples) - 1; + VkPipeline *pipeline; + + pipeline = &device->meta_state.resolve_fragment.rc[samples_log2].pipeline[fs_key]; + if (!*pipeline ) { + VkResult ret; + + ret = create_resolve_pipeline(device, samples_log2, + radv_fs_key_format_exemplars[fs_key]); + if (ret != VK_SUCCESS) { + cmd_buffer->record_result = ret; + return NULL; + } + } + + return pipeline; +} + static void emit_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview, @@ -383,8 +403,8 @@ emit_resolve(struct radv_cmd_buffer *cmd_buffer, { struct radv_device *device = cmd_buffer->device; VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); - const uint32_t samples = src_iview->image->info.samples; - const uint32_t samples_log2 = ffs(samples) - 1; + VkPipeline *pipeline; + radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, cmd_buffer->device->meta_state.resolve_fragment.p_layout, @@ -418,11 +438,10 @@ emit_resolve(struct radv_cmd_buffer *cmd_buffer, VK_SHADER_STAGE_FRAGMENT_BIT, 0, 8, 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]; + pipeline = radv_get_resolve_pipeline(cmd_buffer, src_iview, dest_iview); 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 +480,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,39 +609,25 @@ 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]; - if (src_att.attachment == VK_ATTACHMENT_UNUSED || - dest_att.attachment == VK_ATTACHMENT_UNUSED) + if (dest_att.attachment == VK_ATTACHMENT_UNUSED) continue; struct radv_image_view *dest_iview = cmd_buffer->state.framebuffer->attachments[dest_att.attachment].attachment; @@ -623,10 +636,10 @@ radv_cmd_buffer_resolve_subpass_fs(struct radv_cmd_buffer *cmd_buffer) struct radv_subpass resolve_subpass = { .color_count = 1, .color_attachments = (struct radv_subpass_attachment[]) { dest_att }, - .depth_stencil_attachment = { .attachment = VK_ATTACHMENT_UNUSED }, + .depth_stencil_attachment = NULL, }; - radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass, false); + radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass); emit_resolve(cmd_buffer, src_iview, @@ -636,6 +649,7 @@ radv_cmd_buffer_resolve_subpass_fs(struct radv_cmd_buffer *cmd_buffer) &(VkExtent2D) { fb->width, fb->height }); } - cmd_buffer->state.subpass = subpass; + radv_cmd_buffer_set_subpass(cmd_buffer, subpass); + radv_meta_restore(&saved_state, cmd_buffer); }