From 1746837a711d4d414263e8e86b435050cde9dcfe Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 13 Feb 2026 07:37:15 +0100 Subject: [PATCH] radv/meta: remove CB_RESOLVE CB_RESOLVE isn't very fast and we already have two different paths, it's been removed in hw since GFX11. PAL and RadeonSI removed support for it too. Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/meta/radv_meta.h | 1 - src/amd/vulkan/meta/radv_meta_resolve.c | 378 +----------------------- src/amd/vulkan/nir/radv_meta_nir.c | 15 - src/amd/vulkan/nir/radv_meta_nir.h | 2 - src/amd/vulkan/radv_cmd_buffer.c | 5 +- 5 files changed, 11 insertions(+), 390 deletions(-) diff --git a/src/amd/vulkan/meta/radv_meta.h b/src/amd/vulkan/meta/radv_meta.h index 4ebb8c019c3..a86b80efa4f 100644 --- a/src/amd/vulkan/meta/radv_meta.h +++ b/src/amd/vulkan/meta/radv_meta.h @@ -84,7 +84,6 @@ enum radv_meta_object_key_type { RADV_META_OBJECT_KEY_FMASK_COPY, RADV_META_OBJECT_KEY_FMASK_EXPAND, RADV_META_OBJECT_KEY_FMASK_DECOMPRESS, - RADV_META_OBJECT_KEY_RESOLVE_HW, RADV_META_OBJECT_KEY_RESOLVE_CS, RADV_META_OBJECT_KEY_RESOLVE_GFX, RADV_META_OBJECT_KEY_DGC, diff --git a/src/amd/vulkan/meta/radv_meta_resolve.c b/src/amd/vulkan/meta/radv_meta_resolve.c index 9c7abd2a045..ff1bf3bbe37 100644 --- a/src/amd/vulkan/meta/radv_meta_resolve.c +++ b/src/amd/vulkan/meta/radv_meta_resolve.c @@ -13,181 +13,11 @@ #include "radv_meta.h" #include "vk_format.h" -struct radv_resolve_key { - enum radv_meta_object_key_type type; - VkFormat format; -}; - -static VkResult -get_pipeline(struct radv_device *device, VkFormat format, VkPipeline *pipeline_out, VkPipelineLayout *layout_out) -{ - struct radv_resolve_key key; - VkResult result; - - result = radv_meta_get_noop_pipeline_layout(device, layout_out); - if (result != VK_SUCCESS) - return result; - - memset(&key, 0, sizeof(key)); - key.type = RADV_META_OBJECT_KEY_RESOLVE_HW; - key.format = format; - - VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, &key, sizeof(key)); - if (pipeline_from_cache != VK_NULL_HANDLE) { - *pipeline_out = pipeline_from_cache; - return VK_SUCCESS; - } - - nir_shader *vs_module = radv_meta_nir_build_vs_generate_vertices(device); - nir_shader *fs_module = radv_meta_nir_build_resolve_hw(device); - - const VkGraphicsPipelineCreateInfoRADV radv_info = { - .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO_RADV, - .custom_blend_mode = V_028808_CB_RESOLVE, - }; - - const VkGraphicsPipelineCreateInfo pipeline_create_info = { - .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .pNext = &radv_info, - .stageCount = 2, - .pStages = - (VkPipelineShaderStageCreateInfo[]){ - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_VERTEX_BIT, - .module = vk_shader_module_handle_from_nir(vs_module), - .pName = "main", - }, - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_FRAGMENT_BIT, - .module = vk_shader_module_handle_from_nir(fs_module), - .pName = "main", - }, - }, - .pVertexInputState = - &(VkPipelineVertexInputStateCreateInfo){ - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 0, - .vertexAttributeDescriptionCount = 0, - }, - .pInputAssemblyState = - &(VkPipelineInputAssemblyStateCreateInfo){ - .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - .topology = VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA, - .primitiveRestartEnable = false, - }, - .pViewportState = - &(VkPipelineViewportStateCreateInfo){ - .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .viewportCount = 1, - .scissorCount = 1, - }, - .pRasterizationState = - &(VkPipelineRasterizationStateCreateInfo){ - .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - .depthClampEnable = false, - .rasterizerDiscardEnable = false, - .polygonMode = VK_POLYGON_MODE_FILL, - .cullMode = VK_CULL_MODE_NONE, - .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, - }, - .pMultisampleState = - &(VkPipelineMultisampleStateCreateInfo){ - .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - .rasterizationSamples = 1, - .sampleShadingEnable = false, - .pSampleMask = NULL, - .alphaToCoverageEnable = false, - .alphaToOneEnable = false, - }, - .pColorBlendState = - &(VkPipelineColorBlendStateCreateInfo){ - .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - .logicOpEnable = false, - .attachmentCount = 2, - .pAttachments = - (VkPipelineColorBlendAttachmentState[]){ - { - .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | - VK_COLOR_COMPONENT_A_BIT, - }, - { - .colorWriteMask = 0, - - }}, - }, - .pDynamicState = - &(VkPipelineDynamicStateCreateInfo){ - .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - .dynamicStateCount = 2, - .pDynamicStates = - (VkDynamicState[]){ - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, - }, - }, - .layout = *layout_out, - }; - - struct vk_meta_rendering_info render = { - .color_attachment_count = 2, - .color_attachment_formats = {format, format}, - }; - - result = vk_meta_create_graphics_pipeline(&device->vk, &device->meta_state.device, &pipeline_create_info, &render, - &key, sizeof(key), pipeline_out); - - ralloc_free(vs_module); - ralloc_free(fs_module); - return result; -} - -static void -emit_resolve(struct radv_cmd_buffer *cmd_buffer, const struct radv_image *src_image, const struct radv_image *dst_image, - VkFormat vk_format) -{ - struct radv_device *device = radv_cmd_buffer_device(cmd_buffer); - VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); - VkPipelineLayout layout; - VkPipeline pipeline; - VkResult result; - - result = get_pipeline(device, vk_format, &pipeline, &layout); - if (result != VK_SUCCESS) { - vk_command_buffer_set_error(&cmd_buffer->vk, result); - return; - } - - cmd_buffer->state.flush_bits |= radv_src_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, - VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, 0, src_image, NULL) | - radv_dst_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, - VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT, 0, src_image, NULL); - - radv_meta_bind_graphics_pipeline(cmd_buffer, pipeline); - - radv_CmdDraw(cmd_buffer_h, 3, 1, 0, 0); - cmd_buffer->state.flush_bits |= radv_src_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, - VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, 0, dst_image, NULL); -} - enum radv_resolve_method { - RESOLVE_HW, RESOLVE_COMPUTE, RESOLVE_FRAGMENT, }; -static bool -image_hw_resolve_compat(const struct radv_device *device, struct radv_image *src_image, struct radv_image *dst_image) -{ - const struct radv_physical_device *pdev = radv_device_physical(device); - if (pdev->info.gfx_level >= GFX9) { - return dst_image->planes[0].surface.u.gfx9.swizzle_mode == src_image->planes[0].surface.u.gfx9.swizzle_mode; - } else { - return dst_image->planes[0].surface.micro_tile_mode == src_image->planes[0].surface.micro_tile_mode; - } -} - static void radv_pick_resolve_method_images(struct radv_device *device, struct radv_image *src_image, VkFormat src_format, struct radv_image *dst_image, unsigned dst_level, VkImageLayout dst_image_layout, @@ -204,12 +34,6 @@ radv_pick_resolve_method_images(struct radv_device *device, struct radv_image *s */ if (radv_layout_dcc_compressed(device, dst_image, dst_level, dst_image_layout, queue_mask)) { *method = RESOLVE_FRAGMENT; - } else if (!image_hw_resolve_compat(device, src_image, dst_image)) { - /* The micro tile mode only needs to match for the HW - * resolve path which is the default path for non-DCC - * resolves. - */ - *method = RESOLVE_COMPUTE; } if (src_format == VK_FORMAT_R16G16_UNORM || src_format == VK_FORMAT_R16G16_SNORM) @@ -227,154 +51,6 @@ radv_pick_resolve_method_images(struct radv_device *device, struct radv_image *s } } -static void -radv_meta_resolve_hardware_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image, VkFormat src_format, - VkImageLayout src_image_layout, struct radv_image *dst_image, VkFormat dst_format, - VkImageLayout dst_image_layout, const VkImageResolve2 *region) -{ - struct radv_device *device = radv_cmd_buffer_device(cmd_buffer); - - assert(src_image->vk.samples > 1); - assert(dst_image->vk.samples == 1); - - /* From the Vulkan 1.0 spec: - * - * - The aspectMask member of srcSubresource and dstSubresource must - * only contain VK_IMAGE_ASPECT_COLOR_BIT - */ - assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); - assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); - /* Multi-layer resolves are handled by compute */ - assert(vk_image_subresource_layer_count(&src_image->vk, ®ion->srcSubresource) == 1 && - vk_image_subresource_layer_count(&dst_image->vk, ®ion->dstSubresource) == 1); - /** - * From Vulkan 1.0.6 spec: 18.6 Resolving Multisample Images - * - * extent is the size in texels of the source image to resolve in width, - * height and depth. 1D images use only x and width. 2D images use x, y, - * width and height. 3D images use x, y, z, width, height and depth. - * - * srcOffset and dstOffset select the initial x, y, and z offsets in - * texels of the sub-regions of the source and destination image data. - * extent is the size in texels of the source image to resolve in width, - * height and depth. 1D images use only x and width. 2D images use x, y, - * width and height. 3D images use x, y, z, width, height and depth. - */ - const struct VkExtent3D extent = vk_image_sanitize_extent(&src_image->vk, region->extent); - const struct VkOffset3D dstOffset = vk_image_sanitize_offset(&dst_image->vk, region->dstOffset); - - uint32_t queue_mask = radv_image_queue_family_mask(dst_image, cmd_buffer->qf, cmd_buffer->qf); - - if (radv_layout_dcc_compressed(device, dst_image, region->dstSubresource.mipLevel, dst_image_layout, queue_mask)) { - VkImageSubresourceRange range = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = region->dstSubresource.mipLevel, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - }; - - cmd_buffer->state.flush_bits |= radv_init_dcc(cmd_buffer, dst_image, &range, DCC_UNCOMPRESSED); - } - - VkRect2D resolve_area = { - .offset = {dstOffset.x, dstOffset.y}, - .extent = {extent.width, extent.height}, - }; - - radv_meta_set_viewport_and_scissor(cmd_buffer, resolve_area.offset.x, resolve_area.offset.y, - resolve_area.extent.width, resolve_area.extent.height); - - const VkImageViewUsageCreateInfo src_iview_usage_info = { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, - .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - }; - - struct radv_image_view src_iview; - radv_image_view_init(&src_iview, device, - &(VkImageViewCreateInfo){ - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = &src_iview_usage_info, - .flags = VK_IMAGE_VIEW_CREATE_DRIVER_INTERNAL_BIT_MESA, - .image = radv_image_to_handle(src_image), - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .format = src_format, - .subresourceRange = - { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - }, - }, - NULL); - - const VkImageViewUsageCreateInfo dst_iview_usage_info = { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, - .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - }; - - struct radv_image_view dst_iview; - radv_image_view_init(&dst_iview, device, - &(VkImageViewCreateInfo){ - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = &dst_iview_usage_info, - .flags = VK_IMAGE_VIEW_CREATE_DRIVER_INTERNAL_BIT_MESA, - .image = radv_image_to_handle(dst_image), - .viewType = radv_meta_get_view_type(dst_image), - .format = dst_format, - .subresourceRange = - { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = region->dstSubresource.mipLevel, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - }, - }, - NULL); - - const VkRenderingAttachmentInfo color_atts[2] = { - { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = radv_image_view_to_handle(&src_iview), - .imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - }, - { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = radv_image_view_to_handle(&dst_iview), - .imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - }, - }; - - const VkRenderingInfo rendering_info = { - .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, - .flags = VK_RENDERING_LOCAL_READ_CONCURRENT_ACCESS_CONTROL_BIT_KHR, - .renderArea = resolve_area, - .layerCount = 1, - .colorAttachmentCount = 2, - .pColorAttachments = color_atts, - }; - - radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info); - - emit_resolve(cmd_buffer, src_image, dst_image, dst_format); - - const VkRenderingEndInfoKHR end_info = { - .sType = VK_STRUCTURE_TYPE_RENDERING_END_INFO_KHR, - }; - - radv_CmdEndRendering2KHR(radv_cmd_buffer_to_handle(cmd_buffer), &end_info); - - radv_image_view_finish(&src_iview); - radv_image_view_finish(&dst_iview); -} - /** * Decompress CMask/FMask before resolving a multisampled source image. */ @@ -470,21 +146,13 @@ resolve_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image, const VkResolveModeFlagBits resolve_mode = vk_format_is_int(src_format) ? VK_RESOLVE_MODE_SAMPLE_ZERO_BIT : VK_RESOLVE_MODE_AVERAGE_BIT; - switch (resolve_method) { - case RESOLVE_HW: - radv_meta_resolve_hardware_image(cmd_buffer, src_image, src_format, src_image_layout, dst_image, dst_format, - dst_image_layout, region); - break; - case RESOLVE_FRAGMENT: + if (resolve_method == RESOLVE_FRAGMENT) { radv_gfx_resolve_image(cmd_buffer, src_image, src_format, src_image_layout, dst_image, dst_format, dst_image_layout, resolve_mode, region); - break; - case RESOLVE_COMPUTE: + } else { + assert(resolve_method == RESOLVE_COMPUTE); radv_compute_resolve_image(cmd_buffer, src_image, src_format, src_image_layout, dst_image, dst_format, dst_image_layout, resolve_mode, region); - break; - default: - assert(!"Invalid resolve method selected"); } } } @@ -507,22 +175,6 @@ radv_CmdResolveImage2(VkCommandBuffer commandBuffer, const VkResolveImageInfo2 * radv_meta_begin(cmd_buffer); - /* we can use the hw resolve only for single full resolves */ - if (pResolveImageInfo->regionCount == 1) { - if (pResolveImageInfo->pRegions[0].srcOffset.x || pResolveImageInfo->pRegions[0].srcOffset.y || - pResolveImageInfo->pRegions[0].srcOffset.z) - resolve_method = RESOLVE_COMPUTE; - if (pResolveImageInfo->pRegions[0].dstOffset.x || pResolveImageInfo->pRegions[0].dstOffset.y || - pResolveImageInfo->pRegions[0].dstOffset.z) - resolve_method = RESOLVE_COMPUTE; - - if (pResolveImageInfo->pRegions[0].extent.width != src_image->vk.extent.width || - pResolveImageInfo->pRegions[0].extent.height != src_image->vk.extent.height || - pResolveImageInfo->pRegions[0].extent.depth != src_image->vk.extent.depth) - resolve_method = RESOLVE_COMPUTE; - } else - resolve_method = RESOLVE_COMPUTE; - for (uint32_t r = 0; r < pResolveImageInfo->regionCount; r++) { const VkImageResolve2 *region = &pResolveImageInfo->pRegions[r]; @@ -741,27 +393,15 @@ radv_cmd_buffer_resolve_rendering(struct radv_cmd_buffer *cmd_buffer, const VkRe dst_format = vk_format_no_srgb(dst_format); } - switch (resolve_method) { - case RESOLVE_HW: - radv_meta_resolve_hardware_image(cmd_buffer, src_iview->image, src_format, src_layout, dst_iview->image, - dst_format, dst_layout, ®ion); - break; - case RESOLVE_COMPUTE: - radv_decompress_resolve_src(cmd_buffer, src_iview->image, src_layout, ®ion, NULL); - - radv_compute_resolve_image(cmd_buffer, src_iview->image, src_format, src_layout, dst_iview->image, - dst_format, dst_layout, att->resolveMode, ®ion); - used_compute = true; - break; - case RESOLVE_FRAGMENT: { - radv_decompress_resolve_src(cmd_buffer, src_iview->image, src_layout, ®ion, NULL); + radv_decompress_resolve_src(cmd_buffer, src_iview->image, src_layout, ®ion, NULL); + if (resolve_method == RESOLVE_FRAGMENT) { radv_gfx_resolve_image(cmd_buffer, src_iview->image, src_format, src_layout, dst_iview->image, dst_format, dst_layout, att->resolveMode, ®ion); - break; - } - default: - UNREACHABLE("Invalid resolve method"); + } else { + assert(resolve_method == RESOLVE_COMPUTE); + radv_compute_resolve_image(cmd_buffer, src_iview->image, src_format, src_layout, dst_iview->image, + dst_format, dst_layout, att->resolveMode, ®ion); } } } diff --git a/src/amd/vulkan/nir/radv_meta_nir.c b/src/amd/vulkan/nir/radv_meta_nir.c index 39a9a9ff186..6555474dcd7 100644 --- a/src/amd/vulkan/nir/radv_meta_nir.c +++ b/src/amd/vulkan/nir/radv_meta_nir.c @@ -1355,21 +1355,6 @@ radv_meta_nir_build_resolve_fs(struct radv_device *dev, bool use_fmask, int samp return b.shader; } -nir_shader * -radv_meta_nir_build_resolve_hw(struct radv_device *dev) -{ - const struct glsl_type *vec4 = glsl_vec4_type(); - nir_variable *f_color; - - nir_builder b = radv_meta_nir_init_shader(dev, MESA_SHADER_FRAGMENT, "meta_resolve_hw"); - - f_color = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color"); - f_color->data.location = FRAG_RESULT_DATA0; - nir_store_var(&b, f_color, nir_imm_vec4(&b, 0.0, 0.0, 0.0, 1.0), 0xf); - - return b.shader; -} - nir_shader * radv_meta_nir_build_clear_hiz_compute_shader(struct radv_device *dev, int samples) { diff --git a/src/amd/vulkan/nir/radv_meta_nir.h b/src/amd/vulkan/nir/radv_meta_nir.h index c334026854f..5d4e1d08ce5 100644 --- a/src/amd/vulkan/nir/radv_meta_nir.h +++ b/src/amd/vulkan/nir/radv_meta_nir.h @@ -103,8 +103,6 @@ nir_shader *radv_meta_nir_build_resolve_cs(struct radv_device *dev, bool use_fma nir_shader *radv_meta_nir_build_resolve_fs(struct radv_device *dev, bool use_fmask, int samples, bool is_integer, VkImageAspectFlags aspects, VkResolveModeFlagBits resolve_mode); -nir_shader *radv_meta_nir_build_resolve_hw(struct radv_device *dev); - nir_shader *radv_meta_nir_build_clear_hiz_compute_shader(struct radv_device *dev, int samples); nir_shader *radv_meta_nir_build_copy_memory_indirect_preprocess_cs(struct radv_device *dev); diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 2f68fc60f21..e54f4186f47 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -12200,9 +12200,8 @@ radv_emit_cb_render_state(struct radv_cmd_buffer *cmd_buffer) } if (pdev->info.has_rbplus) { - /* RB+ doesn't work with dual source blending, logic op and CB_RESOLVE. */ - cb_color_control |= S_028808_DISABLE_DUAL_QUAD(mrt0_is_dual_src || d->vk.cb.logic_op_enable || - cmd_buffer->state.custom_blend_mode == V_028808_CB_RESOLVE); + /* RB+ doesn't work with dual source blending and logic op. */ + cb_color_control |= S_028808_DISABLE_DUAL_QUAD(mrt0_is_dual_src || d->vk.cb.logic_op_enable); if (mrt0_is_dual_src) { for (unsigned i = 0; i < MAX_RTS; i++) {