X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_meta_blit2d.c;h=1fb5529b410eaae59eac2cfda21160371cac1552;hb=2a83154b4aa4ae9a86134bfd66f315c91e91302f;hp=f7809b448610fe658182b368384a1ec3ae40b190;hpb=a5f76d259b6af9c7f6ba69b599f6669fa645c572;p=mesa.git diff --git a/src/amd/vulkan/radv_meta_blit2d.c b/src/amd/vulkan/radv_meta_blit2d.c index f7809b44861..1fb5529b410 100644 --- a/src/amd/vulkan/radv_meta_blit2d.c +++ b/src/amd/vulkan/radv_meta_blit2d.c @@ -30,10 +30,27 @@ enum blit2d_src_type { BLIT2D_SRC_TYPE_IMAGE, + BLIT2D_SRC_TYPE_IMAGE_3D, BLIT2D_SRC_TYPE_BUFFER, BLIT2D_NUM_SRC_TYPES, }; +static VkResult +blit2d_init_color_pipeline(struct radv_device *device, + enum blit2d_src_type src_type, + VkFormat format, + uint32_t log2_samples); + +static VkResult +blit2d_init_depth_only_pipeline(struct radv_device *device, + enum blit2d_src_type src_type, + uint32_t log2_samples); + +static VkResult +blit2d_init_stencil_only_pipeline(struct radv_device *device, + enum blit2d_src_type src_type, + uint32_t log2_samples); + static void create_iview(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *surf, @@ -41,6 +58,8 @@ create_iview(struct radv_cmd_buffer *cmd_buffer, VkImageAspectFlagBits aspects) { VkFormat format; + VkImageViewType view_type = cmd_buffer->device->physical_device->rad_info.chip_class < GFX9 ? VK_IMAGE_VIEW_TYPE_2D : + radv_meta_get_view_type(surf->image); if (depth_format) format = depth_format; @@ -51,7 +70,7 @@ create_iview(struct radv_cmd_buffer *cmd_buffer, &(VkImageViewCreateInfo) { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .image = radv_image_to_handle(surf->image), - .viewType = VK_IMAGE_VIEW_TYPE_2D, + .viewType = view_type, .format = format, .subresourceRange = { .aspectMask = aspects, @@ -97,7 +116,8 @@ blit2d_bind_src(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_buffer *src_buf, struct blit2d_src_temps *tmp, enum blit2d_src_type src_type, VkFormat depth_format, - VkImageAspectFlagBits aspects) + VkImageAspectFlagBits aspects, + uint32_t log2_samples) { struct radv_device *device = cmd_buffer->device; @@ -105,7 +125,7 @@ blit2d_bind_src(struct radv_cmd_buffer *cmd_buffer, create_bview(cmd_buffer, src_buf, &tmp->bview, depth_format); radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - device->meta_state.blit2d.p_layouts[src_type], + device->meta_state.blit2d[log2_samples].p_layouts[src_type], 0, /* set */ 1, /* descriptorWriteCount */ (VkWriteDescriptorSet[]) { @@ -120,14 +140,20 @@ blit2d_bind_src(struct radv_cmd_buffer *cmd_buffer, }); radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), - device->meta_state.blit2d.p_layouts[src_type], + device->meta_state.blit2d[log2_samples].p_layouts[src_type], VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4, &src_buf->pitch); } else { create_iview(cmd_buffer, src_img, &tmp->iview, depth_format, aspects); + if (src_type == BLIT2D_SRC_TYPE_IMAGE_3D) + radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), + device->meta_state.blit2d[log2_samples].p_layouts[src_type], + VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4, + &src_img->layer); + radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - device->meta_state.blit2d.p_layouts[src_type], + device->meta_state.blit2d[log2_samples].p_layouts[src_type], 0, /* set */ 1, /* descriptorWriteCount */ (VkWriteDescriptorSet[]) { @@ -181,41 +207,38 @@ blit2d_bind_dst(struct radv_cmd_buffer *cmd_buffer, static void bind_pipeline(struct radv_cmd_buffer *cmd_buffer, - enum blit2d_src_type src_type, unsigned fs_key) + enum blit2d_src_type src_type, unsigned fs_key, + uint32_t log2_samples) { VkPipeline pipeline = - cmd_buffer->device->meta_state.blit2d.pipelines[src_type][fs_key]; + cmd_buffer->device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]; - if (cmd_buffer->state.pipeline != radv_pipeline_from_handle(pipeline)) { - radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), - VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); - } + radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), + VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); } static void bind_depth_pipeline(struct radv_cmd_buffer *cmd_buffer, - enum blit2d_src_type src_type) + enum blit2d_src_type src_type, + uint32_t log2_samples) { VkPipeline pipeline = - cmd_buffer->device->meta_state.blit2d.depth_only_pipeline[src_type]; + cmd_buffer->device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]; - if (cmd_buffer->state.pipeline != radv_pipeline_from_handle(pipeline)) { - radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), - VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); - } + radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), + VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); } static void bind_stencil_pipeline(struct radv_cmd_buffer *cmd_buffer, - enum blit2d_src_type src_type) + enum blit2d_src_type src_type, + uint32_t log2_samples) { VkPipeline pipeline = - cmd_buffer->device->meta_state.blit2d.stencil_only_pipeline[src_type]; + cmd_buffer->device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]; - if (cmd_buffer->state.pipeline != radv_pipeline_from_handle(pipeline)) { - radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), - VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); - } + radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), + VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); } static void @@ -224,7 +247,8 @@ radv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_buffer *src_buf, struct radv_meta_blit2d_surf *dst, unsigned num_rects, - struct radv_meta_blit2d_rect *rects, enum blit2d_src_type src_type) + struct radv_meta_blit2d_rect *rects, enum blit2d_src_type src_type, + uint32_t log2_samples) { struct radv_device *device = cmd_buffer->device; @@ -232,13 +256,17 @@ radv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer, unsigned i; for_each_bit(i, dst->aspect_mask) { unsigned aspect_mask = 1u << i; + unsigned src_aspect_mask = aspect_mask; VkFormat depth_format = 0; if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) depth_format = vk_format_stencil_only(dst->image->vk_format); else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) depth_format = vk_format_depth_only(dst->image->vk_format); + else if (src_img) + src_aspect_mask = src_img->aspect_mask; + struct blit2d_src_temps src_temps; - blit2d_bind_src(cmd_buffer, src_img, src_buf, &src_temps, src_type, depth_format, aspect_mask); + blit2d_bind_src(cmd_buffer, src_img, src_buf, &src_temps, src_type, depth_format, src_aspect_mask, log2_samples); struct blit2d_dst_temps dst_temps; blit2d_bind_dst(cmd_buffer, dst, rects[r].dst_x + rects[r].width, @@ -252,17 +280,29 @@ radv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer, }; radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), - device->meta_state.blit2d.p_layouts[src_type], + device->meta_state.blit2d[log2_samples].p_layouts[src_type], VK_SHADER_STAGE_VERTEX_BIT, 0, 16, vertex_push_constants); - if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) { + if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT || + aspect_mask == VK_IMAGE_ASPECT_PLANE_0_BIT || + aspect_mask == VK_IMAGE_ASPECT_PLANE_1_BIT || + aspect_mask == VK_IMAGE_ASPECT_PLANE_2_BIT) { unsigned fs_key = radv_format_meta_fs_key(dst_temps.iview.vk_format); + unsigned dst_layout = radv_meta_dst_layout_from_layout(dst->current_layout); + + if (device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key] == VK_NULL_HANDLE) { + VkResult ret = blit2d_init_color_pipeline(device, src_type, radv_fs_key_format_exemplars[fs_key], log2_samples); + if (ret != VK_SUCCESS) { + cmd_buffer->record_result = ret; + goto fail_pipeline; + } + } radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer), &(VkRenderPassBeginInfo) { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = device->meta_state.blit2d.render_passes[fs_key], + .renderPass = device->meta_state.blit2d_render_passes[fs_key][dst_layout], .framebuffer = dst_temps.fb, .renderArea = { .offset = { rects[r].dst_x, rects[r].dst_y, }, @@ -273,12 +313,22 @@ radv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer, }, VK_SUBPASS_CONTENTS_INLINE); - bind_pipeline(cmd_buffer, src_type, fs_key); + bind_pipeline(cmd_buffer, src_type, fs_key, log2_samples); } else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) { + enum radv_blit_ds_layout ds_layout = radv_meta_blit_ds_to_type(dst->current_layout); + + if (device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type] == VK_NULL_HANDLE) { + VkResult ret = blit2d_init_depth_only_pipeline(device, src_type, log2_samples); + if (ret != VK_SUCCESS) { + cmd_buffer->record_result = ret; + goto fail_pipeline; + } + } + radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer), &(VkRenderPassBeginInfo) { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = device->meta_state.blit2d.depth_only_rp, + .renderPass = device->meta_state.blit2d_depth_only_rp[ds_layout], .framebuffer = dst_temps.fb, .renderArea = { .offset = { rects[r].dst_x, rects[r].dst_y, }, @@ -289,13 +339,23 @@ radv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer, }, VK_SUBPASS_CONTENTS_INLINE); - bind_depth_pipeline(cmd_buffer, src_type); + bind_depth_pipeline(cmd_buffer, src_type, log2_samples); } else if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) { + enum radv_blit_ds_layout ds_layout = radv_meta_blit_ds_to_type(dst->current_layout); + + if (device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type] == VK_NULL_HANDLE) { + VkResult ret = blit2d_init_stencil_only_pipeline(device, src_type, log2_samples); + if (ret != VK_SUCCESS) { + cmd_buffer->record_result = ret; + goto fail_pipeline; + } + } + radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer), &(VkRenderPassBeginInfo) { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = device->meta_state.blit2d.stencil_only_rp, + .renderPass = device->meta_state.blit2d_stencil_only_rp[ds_layout], .framebuffer = dst_temps.fb, .renderArea = { .offset = { rects[r].dst_x, rects[r].dst_y, }, @@ -306,7 +366,7 @@ radv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer, }, VK_SUBPASS_CONTENTS_INLINE); - bind_stencil_pipeline(cmd_buffer, src_type); + bind_stencil_pipeline(cmd_buffer, src_type, log2_samples); } else unreachable("Processing blit2d with multiple aspects."); @@ -329,6 +389,7 @@ radv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer, radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0); radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer)); +fail_pipeline: /* At the point where we emit the draw call, all data from the * descriptor sets, etc. has been used. We are free to delete it. */ @@ -347,10 +408,13 @@ radv_meta_blit2d(struct radv_cmd_buffer *cmd_buffer, unsigned num_rects, struct radv_meta_blit2d_rect *rects) { + bool use_3d = cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9 && + (src_img && src_img->image->type == VK_IMAGE_TYPE_3D); enum blit2d_src_type src_type = src_buf ? BLIT2D_SRC_TYPE_BUFFER : - BLIT2D_SRC_TYPE_IMAGE; + use_3d ? BLIT2D_SRC_TYPE_IMAGE_3D : BLIT2D_SRC_TYPE_IMAGE; radv_meta_blit2d_normal_dst(cmd_buffer, src_img, src_buf, dst, - num_rects, rects, src_type); + num_rects, rects, src_type, + src_img ? util_logbase2(src_img->image->info.samples) : 0); } static nir_shader * @@ -413,31 +477,63 @@ build_nir_vertex_shader(void) typedef nir_ssa_def* (*texel_fetch_build_func)(struct nir_builder *, struct radv_device *, - nir_ssa_def *); + nir_ssa_def *, bool, bool); static nir_ssa_def * build_nir_texel_fetch(struct nir_builder *b, struct radv_device *device, - nir_ssa_def *tex_pos) + nir_ssa_def *tex_pos, bool is_3d, bool is_multisampled) { + enum glsl_sampler_dim dim = + is_3d ? GLSL_SAMPLER_DIM_3D : is_multisampled ? GLSL_SAMPLER_DIM_MS : GLSL_SAMPLER_DIM_2D; const struct glsl_type *sampler_type = - glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, GLSL_TYPE_UINT); + glsl_sampler_type(dim, false, false, GLSL_TYPE_UINT); nir_variable *sampler = nir_variable_create(b->shader, nir_var_uniform, sampler_type, "s_tex"); sampler->data.descriptor_set = 0; sampler->data.binding = 0; - nir_tex_instr *tex = nir_tex_instr_create(b->shader, 2); - tex->sampler_dim = GLSL_SAMPLER_DIM_2D; - tex->op = nir_texop_txf; + nir_ssa_def *tex_pos_3d = NULL; + nir_intrinsic_instr *sample_idx = NULL; + if (is_3d) { + nir_intrinsic_instr *layer = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_push_constant); + nir_intrinsic_set_base(layer, 16); + nir_intrinsic_set_range(layer, 4); + layer->src[0] = nir_src_for_ssa(nir_imm_int(b, 0)); + layer->num_components = 1; + nir_ssa_dest_init(&layer->instr, &layer->dest, 1, 32, "layer"); + nir_builder_instr_insert(b, &layer->instr); + + nir_ssa_def *chans[3]; + chans[0] = nir_channel(b, tex_pos, 0); + chans[1] = nir_channel(b, tex_pos, 1); + chans[2] = &layer->dest.ssa; + tex_pos_3d = nir_vec(b, chans, 3); + } + if (is_multisampled) { + sample_idx = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_sample_id); + sample_idx->num_components = 1; + nir_ssa_dest_init(&sample_idx->instr, &sample_idx->dest, 1, 32, "sample_idx"); + nir_builder_instr_insert(b, &sample_idx->instr); + } + + nir_ssa_def *tex_deref = &nir_build_deref_var(b, sampler)->dest.ssa; + + nir_tex_instr *tex = nir_tex_instr_create(b->shader, is_multisampled ? 4 : 3); + tex->sampler_dim = dim; + tex->op = is_multisampled ? nir_texop_txf_ms : nir_texop_txf; tex->src[0].src_type = nir_tex_src_coord; - tex->src[0].src = nir_src_for_ssa(tex_pos); - tex->src[1].src_type = nir_tex_src_lod; - tex->src[1].src = nir_src_for_ssa(nir_imm_int(b, 0)); + tex->src[0].src = nir_src_for_ssa(is_3d ? tex_pos_3d : tex_pos); + tex->src[1].src_type = is_multisampled ? nir_tex_src_ms_index : nir_tex_src_lod; + tex->src[1].src = nir_src_for_ssa(is_multisampled ? &sample_idx->dest.ssa : nir_imm_int(b, 0)); + tex->src[2].src_type = nir_tex_src_texture_deref; + tex->src[2].src = nir_src_for_ssa(tex_deref); + if (is_multisampled) { + tex->src[3].src_type = nir_tex_src_lod; + tex->src[3].src = nir_src_for_ssa(nir_imm_int(b, 0)); + } tex->dest_type = nir_type_uint; tex->is_array = false; - tex->coord_components = 2; - tex->texture = nir_deref_var_create(tex, sampler); - tex->sampler = NULL; + tex->coord_components = is_3d ? 3 : 2; nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex"); nir_builder_instr_insert(b, &tex->instr); @@ -448,7 +544,7 @@ build_nir_texel_fetch(struct nir_builder *b, struct radv_device *device, static nir_ssa_def * build_nir_buffer_fetch(struct nir_builder *b, struct radv_device *device, - nir_ssa_def *tex_pos) + nir_ssa_def *tex_pos, bool is_3d, bool is_multisampled) { const struct glsl_type *sampler_type = glsl_sampler_type(GLSL_SAMPLER_DIM_BUF, false, false, GLSL_TYPE_UINT); @@ -469,18 +565,19 @@ build_nir_buffer_fetch(struct nir_builder *b, struct radv_device *device, nir_ssa_def *pos_y = nir_channel(b, tex_pos, 1); pos_y = nir_imul(b, pos_y, &width->dest.ssa); pos_x = nir_iadd(b, pos_x, pos_y); - //pos_x = nir_iadd(b, pos_x, nir_imm_int(b, 100000)); - nir_tex_instr *tex = nir_tex_instr_create(b->shader, 1); + nir_ssa_def *tex_deref = &nir_build_deref_var(b, sampler)->dest.ssa; + + nir_tex_instr *tex = nir_tex_instr_create(b->shader, 2); tex->sampler_dim = GLSL_SAMPLER_DIM_BUF; tex->op = nir_texop_txf; tex->src[0].src_type = nir_tex_src_coord; tex->src[0].src = nir_src_for_ssa(pos_x); + tex->src[1].src_type = nir_tex_src_texture_deref; + tex->src[1].src = nir_src_for_ssa(tex_deref); tex->dest_type = nir_type_uint; tex->is_array = false; tex->coord_components = 1; - tex->texture = nir_deref_var_create(tex, sampler); - tex->sampler = NULL; nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex"); nir_builder_instr_insert(b, &tex->instr); @@ -496,7 +593,8 @@ static const VkPipelineVertexInputStateCreateInfo normal_vi_create_info = { static nir_shader * build_nir_copy_fragment_shader(struct radv_device *device, - texel_fetch_build_func txf_func, const char* name) + texel_fetch_build_func txf_func, const char* name, bool is_3d, + bool is_multisampled) { const struct glsl_type *vec4 = glsl_vec4_type(); const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2); @@ -514,10 +612,9 @@ build_nir_copy_fragment_shader(struct radv_device *device, color_out->data.location = FRAG_RESULT_DATA0; nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in)); - unsigned swiz[4] = { 0, 1 }; - nir_ssa_def *tex_pos = nir_swizzle(&b, pos_int, swiz, 2, false); + nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3); - nir_ssa_def *color = txf_func(&b, device, tex_pos); + nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled); nir_store_var(&b, color_out, color, 0xf); return b.shader; @@ -525,7 +622,8 @@ build_nir_copy_fragment_shader(struct radv_device *device, static nir_shader * build_nir_copy_fragment_shader_depth(struct radv_device *device, - texel_fetch_build_func txf_func, const char* name) + texel_fetch_build_func txf_func, const char* name, bool is_3d, + bool is_multisampled) { const struct glsl_type *vec4 = glsl_vec4_type(); const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2); @@ -543,10 +641,9 @@ build_nir_copy_fragment_shader_depth(struct radv_device *device, color_out->data.location = FRAG_RESULT_DEPTH; nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in)); - unsigned swiz[4] = { 0, 1 }; - nir_ssa_def *tex_pos = nir_swizzle(&b, pos_int, swiz, 2, false); + nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3); - nir_ssa_def *color = txf_func(&b, device, tex_pos); + nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled); nir_store_var(&b, color_out, color, 0x1); return b.shader; @@ -554,7 +651,8 @@ build_nir_copy_fragment_shader_depth(struct radv_device *device, static nir_shader * build_nir_copy_fragment_shader_stencil(struct radv_device *device, - texel_fetch_build_func txf_func, const char* name) + texel_fetch_build_func txf_func, const char* name, bool is_3d, + bool is_multisampled) { const struct glsl_type *vec4 = glsl_vec4_type(); const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2); @@ -572,10 +670,9 @@ build_nir_copy_fragment_shader_stencil(struct radv_device *device, color_out->data.location = FRAG_RESULT_STENCIL; nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in)); - unsigned swiz[4] = { 0, 1 }; - nir_ssa_def *tex_pos = nir_swizzle(&b, pos_int, swiz, 2, false); + nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3); - nir_ssa_def *color = txf_func(&b, device, tex_pos); + nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled); nir_store_var(&b, color_out, color, 0x1); return b.shader; @@ -584,66 +681,74 @@ build_nir_copy_fragment_shader_stencil(struct radv_device *device, void radv_device_finish_meta_blit2d_state(struct radv_device *device) { + struct radv_meta_state *state = &device->meta_state; + for(unsigned j = 0; j < NUM_META_FS_KEYS; ++j) { - if (device->meta_state.blit2d.render_passes[j]) { + for (unsigned k = 0; k < RADV_META_DST_LAYOUT_COUNT; ++k) { radv_DestroyRenderPass(radv_device_to_handle(device), - device->meta_state.blit2d.render_passes[j], - &device->meta_state.alloc); + state->blit2d_render_passes[j][k], + &state->alloc); } } - radv_DestroyRenderPass(radv_device_to_handle(device), - device->meta_state.blit2d.depth_only_rp, - &device->meta_state.alloc); - radv_DestroyRenderPass(radv_device_to_handle(device), - device->meta_state.blit2d.stencil_only_rp, - &device->meta_state.alloc); + for (enum radv_blit_ds_layout j = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; j < RADV_BLIT_DS_LAYOUT_COUNT; j++) { + radv_DestroyRenderPass(radv_device_to_handle(device), + state->blit2d_depth_only_rp[j], &state->alloc); + radv_DestroyRenderPass(radv_device_to_handle(device), + state->blit2d_stencil_only_rp[j], &state->alloc); + } - for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) { - if (device->meta_state.blit2d.p_layouts[src]) { + for (unsigned log2_samples = 0; log2_samples < 1 + MAX_SAMPLES_LOG2; ++log2_samples) { + for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) { radv_DestroyPipelineLayout(radv_device_to_handle(device), - device->meta_state.blit2d.p_layouts[src], - &device->meta_state.alloc); - } - - if (device->meta_state.blit2d.ds_layouts[src]) { + state->blit2d[log2_samples].p_layouts[src], + &state->alloc); radv_DestroyDescriptorSetLayout(radv_device_to_handle(device), - device->meta_state.blit2d.ds_layouts[src], - &device->meta_state.alloc); - } + state->blit2d[log2_samples].ds_layouts[src], + &state->alloc); - for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) { - if (device->meta_state.blit2d.pipelines[src][j]) { + for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) { radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit2d.pipelines[src][j], - &device->meta_state.alloc); + state->blit2d[log2_samples].pipelines[src][j], + &state->alloc); } - } - radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit2d.depth_only_pipeline[src], - &device->meta_state.alloc); - radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit2d.stencil_only_pipeline[src], - &device->meta_state.alloc); + radv_DestroyPipeline(radv_device_to_handle(device), + state->blit2d[log2_samples].depth_only_pipeline[src], + &state->alloc); + radv_DestroyPipeline(radv_device_to_handle(device), + state->blit2d[log2_samples].stencil_only_pipeline[src], + &state->alloc); + } } } static VkResult blit2d_init_color_pipeline(struct radv_device *device, enum blit2d_src_type src_type, - VkFormat format) + VkFormat format, + uint32_t log2_samples) { VkResult result; unsigned fs_key = radv_format_meta_fs_key(format); const char *name; + mtx_lock(&device->meta_state.mtx); + if (device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]) { + mtx_unlock(&device->meta_state.mtx); + return VK_SUCCESS; + } + texel_fetch_build_func src_func; switch(src_type) { case BLIT2D_SRC_TYPE_IMAGE: src_func = build_nir_texel_fetch; name = "meta_blit2d_image_fs"; break; + case BLIT2D_SRC_TYPE_IMAGE_3D: + src_func = build_nir_texel_fetch; + name = "meta_blit3d_image_fs"; + break; case BLIT2D_SRC_TYPE_BUFFER: src_func = build_nir_buffer_fetch; name = "meta_blit2d_buffer_fs"; @@ -657,7 +762,7 @@ blit2d_init_color_pipeline(struct radv_device *device, struct radv_shader_module fs = { .nir = NULL }; - fs.nir = build_nir_copy_fragment_shader(device, src_func, name); + fs.nir = build_nir_copy_fragment_shader(device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0); vi_create_info = &normal_vi_create_info; struct radv_shader_module vs = { @@ -680,37 +785,41 @@ blit2d_init_color_pipeline(struct radv_device *device, }, }; - if (!device->meta_state.blit2d.render_passes[fs_key]) { - result = radv_CreateRenderPass(radv_device_to_handle(device), - &(VkRenderPassCreateInfo) { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - .attachmentCount = 1, - .pAttachments = &(VkAttachmentDescription) { - .format = format, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - }, - .subpassCount = 1, - .pSubpasses = &(VkSubpassDescription) { - .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, - .inputAttachmentCount = 0, - .colorAttachmentCount = 1, - .pColorAttachments = &(VkAttachmentReference) { - .attachment = 0, - .layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + for (unsigned dst_layout = 0; dst_layout < RADV_META_DST_LAYOUT_COUNT; ++dst_layout) { + if (!device->meta_state.blit2d_render_passes[fs_key][dst_layout]) { + VkImageLayout layout = radv_meta_dst_layout_to_layout(dst_layout); + + result = radv_CreateRenderPass(radv_device_to_handle(device), + &(VkRenderPassCreateInfo) { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .attachmentCount = 1, + .pAttachments = &(VkAttachmentDescription) { + .format = format, + .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = layout, + .finalLayout = layout, }, - .pResolveAttachments = NULL, - .pDepthStencilAttachment = &(VkAttachmentReference) { - .attachment = VK_ATTACHMENT_UNUSED, - .layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - }, - .preserveAttachmentCount = 1, - .pPreserveAttachments = (uint32_t[]) { 0 }, - }, - .dependencyCount = 0, - }, &device->meta_state.alloc, &device->meta_state.blit2d.render_passes[fs_key]); + .subpassCount = 1, + .pSubpasses = &(VkSubpassDescription) { + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .inputAttachmentCount = 0, + .colorAttachmentCount = 1, + .pColorAttachments = &(VkAttachmentReference) { + .attachment = 0, + .layout = layout, + }, + .pResolveAttachments = NULL, + .pDepthStencilAttachment = &(VkAttachmentReference) { + .attachment = VK_ATTACHMENT_UNUSED, + .layout = layout, + }, + .preserveAttachmentCount = 0, + .pPreserveAttachments = NULL, + }, + .dependencyCount = 0, + }, &device->meta_state.alloc, &device->meta_state.blit2d_render_passes[fs_key][dst_layout]); + } } const VkGraphicsPipelineCreateInfo vk_pipeline_info = { @@ -737,8 +846,9 @@ blit2d_init_color_pipeline(struct radv_device *device, }, .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - .rasterizationSamples = 1, - .sampleShadingEnable = false, + .rasterizationSamples = 1 << log2_samples, + .sampleShadingEnable = log2_samples > 1, + .minSampleShading = 1.0, .pSampleMask = (VkSampleMask[]) { UINT32_MAX }, }, .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) { @@ -768,8 +878,8 @@ blit2d_init_color_pipeline(struct radv_device *device, }, }, .flags = 0, - .layout = device->meta_state.blit2d.p_layouts[src_type], - .renderPass = device->meta_state.blit2d.render_passes[fs_key], + .layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type], + .renderPass = device->meta_state.blit2d_render_passes[fs_key][0], .subpass = 0, }; @@ -781,28 +891,40 @@ blit2d_init_color_pipeline(struct radv_device *device, radv_pipeline_cache_to_handle(&device->meta_state.cache), &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc, - &device->meta_state.blit2d.pipelines[src_type][fs_key]); + &device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]); ralloc_free(vs.nir); ralloc_free(fs.nir); + mtx_unlock(&device->meta_state.mtx); return result; } static VkResult blit2d_init_depth_only_pipeline(struct radv_device *device, - enum blit2d_src_type src_type) + enum blit2d_src_type src_type, + uint32_t log2_samples) { VkResult result; const char *name; + mtx_lock(&device->meta_state.mtx); + if (device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]) { + mtx_unlock(&device->meta_state.mtx); + return VK_SUCCESS; + } + texel_fetch_build_func src_func; switch(src_type) { case BLIT2D_SRC_TYPE_IMAGE: src_func = build_nir_texel_fetch; name = "meta_blit2d_depth_image_fs"; break; + case BLIT2D_SRC_TYPE_IMAGE_3D: + src_func = build_nir_texel_fetch; + name = "meta_blit3d_depth_image_fs"; + break; case BLIT2D_SRC_TYPE_BUFFER: src_func = build_nir_buffer_fetch; name = "meta_blit2d_depth_buffer_fs"; @@ -815,7 +937,7 @@ blit2d_init_depth_only_pipeline(struct radv_device *device, const VkPipelineVertexInputStateCreateInfo *vi_create_info; struct radv_shader_module fs = { .nir = NULL }; - fs.nir = build_nir_copy_fragment_shader_depth(device, src_func, name); + fs.nir = build_nir_copy_fragment_shader_depth(device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0); vi_create_info = &normal_vi_create_info; struct radv_shader_module vs = { @@ -838,34 +960,37 @@ blit2d_init_depth_only_pipeline(struct radv_device *device, }, }; - if (!device->meta_state.blit2d.depth_only_rp) { - result = radv_CreateRenderPass(radv_device_to_handle(device), - &(VkRenderPassCreateInfo) { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + for (enum radv_blit_ds_layout ds_layout = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; ds_layout < RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) { + if (!device->meta_state.blit2d_depth_only_rp[ds_layout]) { + VkImageLayout layout = radv_meta_blit_ds_to_layout(ds_layout); + result = radv_CreateRenderPass(radv_device_to_handle(device), + &(VkRenderPassCreateInfo) { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, .attachmentCount = 1, .pAttachments = &(VkAttachmentDescription) { - .format = VK_FORMAT_D32_SFLOAT, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - }, - .subpassCount = 1, - .pSubpasses = &(VkSubpassDescription) { - .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, - .inputAttachmentCount = 0, - .colorAttachmentCount = 0, - .pColorAttachments = NULL, - .pResolveAttachments = NULL, - .pDepthStencilAttachment = &(VkAttachmentReference) { - .attachment = 0, - .layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - }, - .preserveAttachmentCount = 1, - .pPreserveAttachments = (uint32_t[]) { 0 }, - }, - .dependencyCount = 0, - }, &device->meta_state.alloc, &device->meta_state.blit2d.depth_only_rp); + .format = VK_FORMAT_D32_SFLOAT, + .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = layout, + .finalLayout = layout, + }, + .subpassCount = 1, + .pSubpasses = &(VkSubpassDescription) { + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .inputAttachmentCount = 0, + .colorAttachmentCount = 0, + .pColorAttachments = NULL, + .pResolveAttachments = NULL, + .pDepthStencilAttachment = &(VkAttachmentReference) { + .attachment = 0, + .layout = layout, + }, + .preserveAttachmentCount = 0, + .pPreserveAttachments = NULL, + }, + .dependencyCount = 0, + }, &device->meta_state.alloc, &device->meta_state.blit2d_depth_only_rp[ds_layout]); + } } const VkGraphicsPipelineCreateInfo vk_pipeline_info = { @@ -892,7 +1017,7 @@ blit2d_init_depth_only_pipeline(struct radv_device *device, }, .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - .rasterizationSamples = 1, + .rasterizationSamples = 1 << log2_samples, .sampleShadingEnable = false, .pSampleMask = (VkSampleMask[]) { UINT32_MAX }, }, @@ -923,8 +1048,8 @@ blit2d_init_depth_only_pipeline(struct radv_device *device, }, }, .flags = 0, - .layout = device->meta_state.blit2d.p_layouts[src_type], - .renderPass = device->meta_state.blit2d.depth_only_rp, + .layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type], + .renderPass = device->meta_state.blit2d_depth_only_rp[0], .subpass = 0, }; @@ -936,28 +1061,40 @@ blit2d_init_depth_only_pipeline(struct radv_device *device, radv_pipeline_cache_to_handle(&device->meta_state.cache), &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc, - &device->meta_state.blit2d.depth_only_pipeline[src_type]); + &device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]); ralloc_free(vs.nir); ralloc_free(fs.nir); + mtx_unlock(&device->meta_state.mtx); return result; } static VkResult blit2d_init_stencil_only_pipeline(struct radv_device *device, - enum blit2d_src_type src_type) + enum blit2d_src_type src_type, + uint32_t log2_samples) { VkResult result; const char *name; + mtx_lock(&device->meta_state.mtx); + if (device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]) { + mtx_unlock(&device->meta_state.mtx); + return VK_SUCCESS; + } + texel_fetch_build_func src_func; switch(src_type) { case BLIT2D_SRC_TYPE_IMAGE: src_func = build_nir_texel_fetch; name = "meta_blit2d_stencil_image_fs"; break; + case BLIT2D_SRC_TYPE_IMAGE_3D: + src_func = build_nir_texel_fetch; + name = "meta_blit3d_stencil_image_fs"; + break; case BLIT2D_SRC_TYPE_BUFFER: src_func = build_nir_buffer_fetch; name = "meta_blit2d_stencil_buffer_fs"; @@ -970,7 +1107,7 @@ blit2d_init_stencil_only_pipeline(struct radv_device *device, const VkPipelineVertexInputStateCreateInfo *vi_create_info; struct radv_shader_module fs = { .nir = NULL }; - fs.nir = build_nir_copy_fragment_shader_stencil(device, src_func, name); + fs.nir = build_nir_copy_fragment_shader_stencil(device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0); vi_create_info = &normal_vi_create_info; struct radv_shader_module vs = { @@ -993,34 +1130,37 @@ blit2d_init_stencil_only_pipeline(struct radv_device *device, }, }; - if (!device->meta_state.blit2d.stencil_only_rp) { - result = radv_CreateRenderPass(radv_device_to_handle(device), - &(VkRenderPassCreateInfo) { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + for (enum radv_blit_ds_layout ds_layout = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; ds_layout < RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) { + if (!device->meta_state.blit2d_stencil_only_rp[ds_layout]) { + VkImageLayout layout = radv_meta_blit_ds_to_layout(ds_layout); + result = radv_CreateRenderPass(radv_device_to_handle(device), + &(VkRenderPassCreateInfo) { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, .attachmentCount = 1, .pAttachments = &(VkAttachmentDescription) { - .format = VK_FORMAT_S8_UINT, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - }, - .subpassCount = 1, - .pSubpasses = &(VkSubpassDescription) { - .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, - .inputAttachmentCount = 0, - .colorAttachmentCount = 0, - .pColorAttachments = NULL, - .pResolveAttachments = NULL, - .pDepthStencilAttachment = &(VkAttachmentReference) { - .attachment = 0, - .layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - }, - .preserveAttachmentCount = 1, - .pPreserveAttachments = (uint32_t[]) { 0 }, - }, - .dependencyCount = 0, - }, &device->meta_state.alloc, &device->meta_state.blit2d.stencil_only_rp); + .format = VK_FORMAT_S8_UINT, + .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = layout, + .finalLayout = layout, + }, + .subpassCount = 1, + .pSubpasses = &(VkSubpassDescription) { + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .inputAttachmentCount = 0, + .colorAttachmentCount = 0, + .pColorAttachments = NULL, + .pResolveAttachments = NULL, + .pDepthStencilAttachment = &(VkAttachmentReference) { + .attachment = 0, + .layout = layout, + }, + .preserveAttachmentCount = 0, + .pPreserveAttachments = NULL, + }, + .dependencyCount = 0, + }, &device->meta_state.alloc, &device->meta_state.blit2d_stencil_only_rp[ds_layout]); + } } const VkGraphicsPipelineCreateInfo vk_pipeline_info = { @@ -1047,7 +1187,7 @@ blit2d_init_stencil_only_pipeline(struct radv_device *device, }, .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - .rasterizationSamples = 1, + .rasterizationSamples = 1 << log2_samples, .sampleShadingEnable = false, .pSampleMask = (VkSampleMask[]) { UINT32_MAX }, }, @@ -1094,8 +1234,8 @@ blit2d_init_stencil_only_pipeline(struct radv_device *device, }, }, .flags = 0, - .layout = device->meta_state.blit2d.p_layouts[src_type], - .renderPass = device->meta_state.blit2d.stencil_only_rp, + .layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type], + .renderPass = device->meta_state.blit2d_stencil_only_rp[0], .subpass = 0, }; @@ -1107,56 +1247,44 @@ blit2d_init_stencil_only_pipeline(struct radv_device *device, radv_pipeline_cache_to_handle(&device->meta_state.cache), &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc, - &device->meta_state.blit2d.stencil_only_pipeline[src_type]); + &device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]); ralloc_free(vs.nir); ralloc_free(fs.nir); + mtx_unlock(&device->meta_state.mtx); return result; } -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 -}; - -VkResult -radv_device_init_meta_blit2d_state(struct radv_device *device) +static VkResult +meta_blit2d_create_pipe_layout(struct radv_device *device, + int idx, + uint32_t log2_samples) { VkResult result; - - zero(device->meta_state.blit2d); - + VkDescriptorType desc_type = (idx == BLIT2D_SRC_TYPE_BUFFER) ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; const VkPushConstantRange push_constant_ranges[] = { {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4}, }; + int num_push_constant_range = (idx != BLIT2D_SRC_TYPE_IMAGE || log2_samples > 0) ? 2 : 1; + result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &(VkDescriptorSetLayoutCreateInfo) { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, - .bindingCount = 1, - .pBindings = (VkDescriptorSetLayoutBinding[]) { - { - .binding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - .pImmutableSamplers = NULL - }, + .bindingCount = 1, + .pBindings = (VkDescriptorSetLayoutBinding[]) { + { + .binding = 0, + .descriptorType = desc_type, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = NULL + }, } - }, &device->meta_state.alloc, &device->meta_state.blit2d.ds_layouts[BLIT2D_SRC_TYPE_IMAGE]); + }, &device->meta_state.alloc, &device->meta_state.blit2d[log2_samples].ds_layouts[idx]); if (result != VK_SUCCESS) goto fail; @@ -1164,59 +1292,54 @@ radv_device_init_meta_blit2d_state(struct radv_device *device) &(VkPipelineLayoutCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .setLayoutCount = 1, - .pSetLayouts = &device->meta_state.blit2d.ds_layouts[BLIT2D_SRC_TYPE_IMAGE], - .pushConstantRangeCount = 1, + .pSetLayouts = &device->meta_state.blit2d[log2_samples].ds_layouts[idx], + .pushConstantRangeCount = num_push_constant_range, .pPushConstantRanges = push_constant_ranges, }, - &device->meta_state.alloc, &device->meta_state.blit2d.p_layouts[BLIT2D_SRC_TYPE_IMAGE]); + &device->meta_state.alloc, &device->meta_state.blit2d[log2_samples].p_layouts[idx]); if (result != VK_SUCCESS) goto fail; + return VK_SUCCESS; +fail: + return result; +} - result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), - &(VkDescriptorSetLayoutCreateInfo) { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, - .bindingCount = 1, - .pBindings = (VkDescriptorSetLayoutBinding[]) { - { - .binding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - .pImmutableSamplers = NULL - }, - } - }, &device->meta_state.alloc, &device->meta_state.blit2d.ds_layouts[BLIT2D_SRC_TYPE_BUFFER]); - if (result != VK_SUCCESS) - goto fail; +VkResult +radv_device_init_meta_blit2d_state(struct radv_device *device, bool on_demand) +{ + VkResult result; + bool create_3d = device->physical_device->rad_info.chip_class >= GFX9; + for (unsigned log2_samples = 0; log2_samples < 1 + MAX_SAMPLES_LOG2; log2_samples++) { + for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) { + if (src == BLIT2D_SRC_TYPE_IMAGE_3D && !create_3d) + continue; - result = radv_CreatePipelineLayout(radv_device_to_handle(device), - &(VkPipelineLayoutCreateInfo) { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .setLayoutCount = 1, - .pSetLayouts = &device->meta_state.blit2d.ds_layouts[BLIT2D_SRC_TYPE_BUFFER], - .pushConstantRangeCount = 2, - .pPushConstantRanges = push_constant_ranges, - }, - &device->meta_state.alloc, &device->meta_state.blit2d.p_layouts[BLIT2D_SRC_TYPE_BUFFER]); - if (result != VK_SUCCESS) - goto fail; + /* Don't need to handle copies between buffers and multisample images. */ + if (src == BLIT2D_SRC_TYPE_BUFFER && log2_samples > 0) + continue; - for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) { - for (unsigned j = 0; j < ARRAY_SIZE(pipeline_formats); ++j) { - result = blit2d_init_color_pipeline(device, src, pipeline_formats[j]); + result = meta_blit2d_create_pipe_layout(device, src, log2_samples); if (result != VK_SUCCESS) goto fail; - } - result = blit2d_init_depth_only_pipeline(device, src); - if (result != VK_SUCCESS) - goto fail; + if (on_demand) + continue; - result = blit2d_init_stencil_only_pipeline(device, src); - if (result != VK_SUCCESS) - goto fail; + for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) { + result = blit2d_init_color_pipeline(device, src, radv_fs_key_format_exemplars[j], log2_samples); + if (result != VK_SUCCESS) + goto fail; + } + + result = blit2d_init_depth_only_pipeline(device, src, log2_samples); + if (result != VK_SUCCESS) + goto fail; + + result = blit2d_init_stencil_only_pipeline(device, src, log2_samples); + if (result != VK_SUCCESS) + goto fail; + } } return VK_SUCCESS;