X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_meta_blit2d.c;h=e163056257e0356b790013e19a3d1aa642d6426c;hb=b462ceb482471dd4aacdd5fa7cef9fe25f823d70;hp=e6848de7e9762c99e9833482d0d533f29f45c299;hpb=4083a2ddcb02a6e79bcc21b3f5b20e10dcef73b1;p=mesa.git diff --git a/src/amd/vulkan/radv_meta_blit2d.c b/src/amd/vulkan/radv_meta_blit2d.c index e6848de7e97..e163056257e 100644 --- a/src/amd/vulkan/radv_meta_blit2d.c +++ b/src/amd/vulkan/radv_meta_blit2d.c @@ -28,24 +28,9 @@ #include "nir/nir_builder.h" #include "vk_format.h" -enum blit2d_dst_type { - /* We can bind this destination as a "normal" render target and render - * to it just like you would anywhere else. - */ - BLIT2D_DST_TYPE_NORMAL, - - /* The destination has a 3-channel RGB format. Since we can't render to - * non-power-of-two textures, we have to bind it as a red texture and - * select the correct component for the given red pixel in the shader. - */ - BLIT2D_DST_TYPE_RGB, - - BLIT2D_NUM_DST_TYPES, -}; - - enum blit2d_src_type { BLIT2D_SRC_TYPE_IMAGE, + BLIT2D_SRC_TYPE_IMAGE_3D, BLIT2D_SRC_TYPE_BUFFER, BLIT2D_NUM_SRC_TYPES, }; @@ -53,10 +38,12 @@ enum blit2d_src_type { static void create_iview(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *surf, - VkImageUsageFlags usage, - struct radv_image_view *iview, VkFormat depth_format) + struct radv_image_view *iview, VkFormat depth_format, + 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; @@ -67,16 +54,16 @@ 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 = surf->aspect_mask, + .aspectMask = aspects, .baseMipLevel = surf->level, .levelCount = 1, .baseArrayLayer = surf->layer, .layerCount = 1 }, - }, cmd_buffer, usage); + }); } static void @@ -98,14 +85,12 @@ create_bview(struct radv_cmd_buffer *cmd_buffer, .format = format, .offset = src->offset, .range = VK_WHOLE_SIZE, - }, cmd_buffer); + }); } struct blit2d_src_temps { struct radv_image_view iview; - - VkDescriptorSet set; struct radv_buffer_view bview; }; @@ -114,78 +99,63 @@ blit2d_bind_src(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src_img, struct radv_meta_blit2d_buffer *src_buf, struct blit2d_src_temps *tmp, - enum blit2d_src_type src_type, VkFormat depth_format) + enum blit2d_src_type src_type, VkFormat depth_format, + VkImageAspectFlagBits aspects) { struct radv_device *device = cmd_buffer->device; - VkDevice vk_device = radv_device_to_handle(cmd_buffer->device); if (src_type == BLIT2D_SRC_TYPE_BUFFER) { create_bview(cmd_buffer, src_buf, &tmp->bview, depth_format); - radv_temp_descriptor_set_create(cmd_buffer->device, cmd_buffer, - device->meta_state.blit2d.ds_layouts[src_type], - &tmp->set); - - radv_UpdateDescriptorSets(vk_device, - 1, /* writeCount */ - (VkWriteDescriptorSet[]) { - { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = tmp->set, - .dstBinding = 0, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, - .pTexelBufferView = (VkBufferView[]) { radv_buffer_view_to_handle(&tmp->bview) } - } - }, 0, NULL); + radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + device->meta_state.blit2d.p_layouts[src_type], + 0, /* set */ + 1, /* descriptorWriteCount */ + (VkWriteDescriptorSet[]) { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + .pTexelBufferView = (VkBufferView[]) { radv_buffer_view_to_handle(&tmp->bview) } + } + }); radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), device->meta_state.blit2d.p_layouts[src_type], - VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4, + VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4, &src_buf->pitch); } else { - create_iview(cmd_buffer, src_img, VK_IMAGE_USAGE_SAMPLED_BIT, &tmp->iview, - depth_format); - - radv_temp_descriptor_set_create(cmd_buffer->device, cmd_buffer, - device->meta_state.blit2d.ds_layouts[src_type], - &tmp->set); - - radv_UpdateDescriptorSets(vk_device, - 1, /* writeCount */ - (VkWriteDescriptorSet[]) { - { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = tmp->set, - .dstBinding = 0, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .pImageInfo = (VkDescriptorImageInfo[]) { - { - .sampler = VK_NULL_HANDLE, - .imageView = radv_image_view_to_handle(&tmp->iview), - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - }, - } - } - }, 0, NULL); - + 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.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], + 0, /* set */ + 1, /* descriptorWriteCount */ + (VkWriteDescriptorSet[]) { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .pImageInfo = (VkDescriptorImageInfo[]) { + { + .sampler = VK_NULL_HANDLE, + .imageView = radv_image_view_to_handle(&tmp->iview), + .imageLayout = VK_IMAGE_LAYOUT_GENERAL, + }, + } + } + }); } - - radv_CmdBindDescriptorSets(radv_cmd_buffer_to_handle(cmd_buffer), - VK_PIPELINE_BIND_POINT_GRAPHICS, - device->meta_state.blit2d.p_layouts[src_type], 0, 1, - &tmp->set, 0, NULL); -} - -static void -blit2d_unbind_src(struct radv_cmd_buffer *cmd_buffer, - struct blit2d_src_temps *tmp, - enum blit2d_src_type src_type) -{ - radv_temp_descriptor_set_destroy(cmd_buffer->device, tmp->set); } struct blit2d_dst_temps { @@ -200,17 +170,10 @@ blit2d_bind_dst(struct radv_cmd_buffer *cmd_buffer, uint32_t width, uint32_t height, VkFormat depth_format, - struct blit2d_dst_temps *tmp) + struct blit2d_dst_temps *tmp, + VkImageAspectFlagBits aspects) { - VkImageUsageFlagBits bits; - - if (dst->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) - bits = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - else - bits = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - - create_iview(cmd_buffer, dst, bits, - &tmp->iview, depth_format); + create_iview(cmd_buffer, dst, &tmp->iview, depth_format, aspects); radv_CreateFramebuffer(radv_device_to_handle(cmd_buffer->device), &(VkFramebufferCreateInfo) { @@ -225,14 +188,6 @@ blit2d_bind_dst(struct radv_cmd_buffer *cmd_buffer, }, &cmd_buffer->pool->alloc, &tmp->fb); } -static void -blit2d_unbind_dst(struct radv_cmd_buffer *cmd_buffer, - struct blit2d_dst_temps *tmp) -{ - VkDevice vk_device = radv_device_to_handle(cmd_buffer->device); - radv_DestroyFramebuffer(vk_device, tmp->fb, &cmd_buffer->pool->alloc); -} - static void bind_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type, unsigned fs_key) @@ -240,10 +195,8 @@ bind_pipeline(struct radv_cmd_buffer *cmd_buffer, VkPipeline pipeline = cmd_buffer->device->meta_state.blit2d.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 @@ -253,10 +206,8 @@ bind_depth_pipeline(struct radv_cmd_buffer *cmd_buffer, VkPipeline pipeline = cmd_buffer->device->meta_state.blit2d.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 @@ -266,10 +217,8 @@ bind_stencil_pipeline(struct radv_cmd_buffer *cmd_buffer, VkPipeline pipeline = cmd_buffer->device->meta_state.blit2d.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 @@ -283,155 +232,116 @@ radv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer, struct radv_device *device = cmd_buffer->device; for (unsigned r = 0; r < num_rects; ++r) { - VkFormat depth_format = 0; - if (dst->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) - depth_format = vk_format_stencil_only(dst->image->vk_format); - else if (dst->aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) - depth_format = vk_format_depth_only(dst->image->vk_format); - struct blit2d_src_temps src_temps; - blit2d_bind_src(cmd_buffer, src_img, src_buf, &src_temps, src_type, depth_format); - - uint32_t offset = 0; - struct blit2d_dst_temps dst_temps; - blit2d_bind_dst(cmd_buffer, dst, rects[r].dst_x + rects[r].width, - rects[r].dst_y + rects[r].height, depth_format, &dst_temps); - - struct blit_vb_data { - float pos[2]; - float tex_coord[2]; - } vb_data[3]; - - unsigned vb_size = 3 * sizeof(*vb_data); - - vb_data[0] = (struct blit_vb_data) { - .pos = { - -1.0, - -1.0, - }, - .tex_coord = { + unsigned i; + for_each_bit(i, dst->aspect_mask) { + unsigned aspect_mask = 1u << i; + 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); + struct blit2d_src_temps src_temps; + blit2d_bind_src(cmd_buffer, src_img, src_buf, &src_temps, src_type, depth_format, aspect_mask); + + struct blit2d_dst_temps dst_temps; + blit2d_bind_dst(cmd_buffer, dst, rects[r].dst_x + rects[r].width, + rects[r].dst_y + rects[r].height, depth_format, &dst_temps, aspect_mask); + + float vertex_push_constants[4] = { rects[r].src_x, rects[r].src_y, - }, - }; - - vb_data[1] = (struct blit_vb_data) { - .pos = { - -1.0, - 1.0, - }, - .tex_coord = { - rects[r].src_x, + rects[r].src_x + rects[r].width, rects[r].src_y + rects[r].height, - }, - }; + }; + + radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), + device->meta_state.blit2d.p_layouts[src_type], + VK_SHADER_STAGE_VERTEX_BIT, 0, 16, + vertex_push_constants); + + if (aspect_mask == VK_IMAGE_ASPECT_COLOR_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); + + 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][dst_layout], + .framebuffer = dst_temps.fb, + .renderArea = { + .offset = { rects[r].dst_x, rects[r].dst_y, }, + .extent = { rects[r].width, rects[r].height }, + }, + .clearValueCount = 0, + .pClearValues = NULL, + }, VK_SUBPASS_CONTENTS_INLINE); + + + bind_pipeline(cmd_buffer, src_type, fs_key); + } 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); + 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[ds_layout], + .framebuffer = dst_temps.fb, + .renderArea = { + .offset = { rects[r].dst_x, rects[r].dst_y, }, + .extent = { rects[r].width, rects[r].height }, + }, + .clearValueCount = 0, + .pClearValues = NULL, + }, VK_SUBPASS_CONTENTS_INLINE); + + + bind_depth_pipeline(cmd_buffer, src_type); + + } 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); + 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[ds_layout], + .framebuffer = dst_temps.fb, + .renderArea = { + .offset = { rects[r].dst_x, rects[r].dst_y, }, + .extent = { rects[r].width, rects[r].height }, + }, + .clearValueCount = 0, + .pClearValues = NULL, + }, VK_SUBPASS_CONTENTS_INLINE); - vb_data[2] = (struct blit_vb_data) { - .pos = { - 1.0, - -1.0, - }, - .tex_coord = { - rects[r].src_x + rects[r].width, - rects[r].src_y, - }, - }; - - - radv_cmd_buffer_upload_data(cmd_buffer, vb_size, 16, vb_data, &offset); - - struct radv_buffer vertex_buffer = { - .device = device, - .size = vb_size, - .bo = cmd_buffer->upload.upload_bo, - .offset = offset, - }; - - radv_CmdBindVertexBuffers(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, - (VkBuffer[]) { - radv_buffer_to_handle(&vertex_buffer), - }, - (VkDeviceSize[]) { - 0, - }); - - - if (dst->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) { - unsigned fs_key = radv_format_meta_fs_key(dst_temps.iview.vk_format); - - 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], - .framebuffer = dst_temps.fb, - .renderArea = { - .offset = { rects[r].dst_x, rects[r].dst_y, }, - .extent = { rects[r].width, rects[r].height }, - }, - .clearValueCount = 0, - .pClearValues = NULL, - }, VK_SUBPASS_CONTENTS_INLINE); - - - bind_pipeline(cmd_buffer, src_type, fs_key); - } else if (dst->aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) { - 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, - .framebuffer = dst_temps.fb, - .renderArea = { - .offset = { rects[r].dst_x, rects[r].dst_y, }, - .extent = { rects[r].width, rects[r].height }, - }, - .clearValueCount = 0, - .pClearValues = NULL, - }, VK_SUBPASS_CONTENTS_INLINE); - - - bind_depth_pipeline(cmd_buffer, src_type); - - } else if (dst->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) { - 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, - .framebuffer = dst_temps.fb, - .renderArea = { - .offset = { rects[r].dst_x, rects[r].dst_y, }, - .extent = { rects[r].width, rects[r].height }, - }, - .clearValueCount = 0, - .pClearValues = NULL, - }, VK_SUBPASS_CONTENTS_INLINE); - - - bind_stencil_pipeline(cmd_buffer, src_type); - } - radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) { - .x = rects[r].dst_x, - .y = rects[r].dst_y, - .width = rects[r].width, - .height = rects[r].height, - .minDepth = 0.0f, - .maxDepth = 1.0f - }); + bind_stencil_pipeline(cmd_buffer, src_type); + } else + unreachable("Processing blit2d with multiple aspects."); + + radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) { + .x = rects[r].dst_x, + .y = rects[r].dst_y, + .width = rects[r].width, + .height = rects[r].height, + .minDepth = 0.0f, + .maxDepth = 1.0f + }); - radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkRect2D) { - .offset = (VkOffset2D) { rects[r].dst_x, rects[r].dst_y }, - .extent = (VkExtent2D) { rects[r].width, rects[r].height }, - }); + radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkRect2D) { + .offset = (VkOffset2D) { rects[r].dst_x, rects[r].dst_y }, + .extent = (VkExtent2D) { rects[r].width, rects[r].height }, + }); - radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0); - radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer)); + radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0); + radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer)); - /* 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. - */ - blit2d_unbind_src(cmd_buffer, &src_temps, src_type); - blit2d_unbind_dst(cmd_buffer, &dst_temps); + /* 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. + */ + radv_DestroyFramebuffer(radv_device_to_handle(device), + dst_temps.fb, + &cmd_buffer->pool->alloc); + } } } @@ -443,8 +353,10 @@ 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); } @@ -457,53 +369,98 @@ build_nir_vertex_shader(void) nir_builder b; nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_VERTEX, NULL); - b.shader->info->name = ralloc_strdup(b.shader, "meta_blit_vs"); + b.shader->info.name = ralloc_strdup(b.shader, "meta_blit2d_vs"); - nir_variable *pos_in = nir_variable_create(b.shader, nir_var_shader_in, - vec4, "a_pos"); - pos_in->data.location = VERT_ATTRIB_GENERIC0; nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "gl_Position"); pos_out->data.location = VARYING_SLOT_POS; - nir_copy_var(&b, pos_out, pos_in); - nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, - vec2, "a_tex_pos"); - tex_pos_in->data.location = VERT_ATTRIB_GENERIC1; nir_variable *tex_pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec2, "v_tex_pos"); tex_pos_out->data.location = VARYING_SLOT_VAR0; tex_pos_out->data.interpolation = INTERP_MODE_SMOOTH; - nir_copy_var(&b, tex_pos_out, tex_pos_in); + nir_ssa_def *outvec = radv_meta_gen_rect_vertices(&b); + nir_store_var(&b, pos_out, outvec, 0xf); + + nir_intrinsic_instr *src_box = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_push_constant); + src_box->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0)); + nir_intrinsic_set_base(src_box, 0); + nir_intrinsic_set_range(src_box, 16); + src_box->num_components = 4; + nir_ssa_dest_init(&src_box->instr, &src_box->dest, 4, 32, "src_box"); + nir_builder_instr_insert(&b, &src_box->instr); + + nir_intrinsic_instr *vertex_id = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_vertex_id_zero_base); + nir_ssa_dest_init(&vertex_id->instr, &vertex_id->dest, 1, 32, "vertexid"); + nir_builder_instr_insert(&b, &vertex_id->instr); + + /* vertex 0 - src_x, src_y */ + /* vertex 1 - src_x, src_y+h */ + /* vertex 2 - src_x+w, src_y */ + /* so channel 0 is vertex_id != 2 ? src_x : src_x + w + channel 1 is vertex id != 1 ? src_y : src_y + w */ + + nir_ssa_def *c0cmp = nir_ine(&b, &vertex_id->dest.ssa, + nir_imm_int(&b, 2)); + nir_ssa_def *c1cmp = nir_ine(&b, &vertex_id->dest.ssa, + nir_imm_int(&b, 1)); + + nir_ssa_def *comp[2]; + comp[0] = nir_bcsel(&b, c0cmp, + nir_channel(&b, &src_box->dest.ssa, 0), + nir_channel(&b, &src_box->dest.ssa, 2)); + + comp[1] = nir_bcsel(&b, c1cmp, + nir_channel(&b, &src_box->dest.ssa, 1), + nir_channel(&b, &src_box->dest.ssa, 3)); + nir_ssa_def *out_tex_vec = nir_vec(&b, comp, 2); + nir_store_var(&b, tex_pos_out, out_tex_vec, 0x3); return b.shader; } typedef nir_ssa_def* (*texel_fetch_build_func)(struct nir_builder *, struct radv_device *, - nir_ssa_def *); + nir_ssa_def *, 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) { + enum glsl_sampler_dim dim = is_3d ? GLSL_SAMPLER_DIM_3D : 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_ssa_def *tex_pos_3d = 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); + } nir_tex_instr *tex = nir_tex_instr_create(b->shader, 2); - tex->sampler_dim = GLSL_SAMPLER_DIM_2D; + tex->sampler_dim = dim; tex->op = nir_texop_txf; tex->src[0].src_type = nir_tex_src_coord; - tex->src[0].src = nir_src_for_ssa(tex_pos); + tex->src[0].src = nir_src_for_ssa(is_3d ? tex_pos_3d : 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->dest_type = nir_type_uint; tex->is_array = false; - tex->coord_components = 2; + tex->coord_components = is_3d ? 3 : 2; tex->texture = nir_deref_var_create(tex, sampler); tex->sampler = NULL; @@ -516,7 +473,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) { const struct glsl_type *sampler_type = glsl_sampler_type(GLSL_SAMPLER_DIM_BUF, false, false, GLSL_TYPE_UINT); @@ -526,6 +483,8 @@ build_nir_buffer_fetch(struct nir_builder *b, struct radv_device *device, sampler->data.binding = 0; nir_intrinsic_instr *width = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_push_constant); + nir_intrinsic_set_base(width, 16); + nir_intrinsic_set_range(width, 4); width->src[0] = nir_src_for_ssa(nir_imm_int(b, 0)); width->num_components = 1; nir_ssa_dest_init(&width->instr, &width->dest, 1, 32, "width"); @@ -556,43 +515,20 @@ build_nir_buffer_fetch(struct nir_builder *b, struct radv_device *device, static const VkPipelineVertexInputStateCreateInfo normal_vi_create_info = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 1, - .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) { - { - .binding = 0, - .stride = 4 * sizeof(float), - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX - }, - }, - .vertexAttributeDescriptionCount = 2, - .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) { - { - /* Position */ - .location = 0, - .binding = 0, - .format = VK_FORMAT_R32G32_SFLOAT, - .offset = 0 - }, - { - /* Texture Coordinate */ - .location = 1, - .binding = 0, - .format = VK_FORMAT_R32G32_SFLOAT, - .offset = 8 - }, - }, + .vertexBindingDescriptionCount = 0, + .vertexAttributeDescriptionCount = 0, }; 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) { const struct glsl_type *vec4 = glsl_vec4_type(); const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2); nir_builder b; nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL); - b.shader->info->name = ralloc_strdup(b.shader, name); + b.shader->info.name = ralloc_strdup(b.shader, name); nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos"); @@ -606,7 +542,7 @@ build_nir_copy_fragment_shader(struct radv_device *device, unsigned swiz[4] = { 0, 1 }; nir_ssa_def *tex_pos = nir_swizzle(&b, pos_int, swiz, 2, false); - nir_ssa_def *color = txf_func(&b, device, tex_pos); + nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d); nir_store_var(&b, color_out, color, 0xf); return b.shader; @@ -614,14 +550,14 @@ 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) { const struct glsl_type *vec4 = glsl_vec4_type(); const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2); nir_builder b; nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL); - b.shader->info->name = ralloc_strdup(b.shader, name); + b.shader->info.name = ralloc_strdup(b.shader, name); nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos"); @@ -635,7 +571,7 @@ build_nir_copy_fragment_shader_depth(struct radv_device *device, unsigned swiz[4] = { 0, 1 }; nir_ssa_def *tex_pos = nir_swizzle(&b, pos_int, swiz, 2, false); - nir_ssa_def *color = txf_func(&b, device, tex_pos); + nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d); nir_store_var(&b, color_out, color, 0x1); return b.shader; @@ -643,14 +579,14 @@ 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) { const struct glsl_type *vec4 = glsl_vec4_type(); const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2); nir_builder b; nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL); - b.shader->info->name = ralloc_strdup(b.shader, name); + b.shader->info.name = ralloc_strdup(b.shader, name); nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos"); @@ -664,7 +600,7 @@ build_nir_copy_fragment_shader_stencil(struct radv_device *device, unsigned swiz[4] = { 0, 1 }; nir_ssa_def *tex_pos = nir_swizzle(&b, pos_int, swiz, 2, false); - nir_ssa_def *color = txf_func(&b, device, tex_pos); + nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d); nir_store_var(&b, color_out, color, 0x1); return b.shader; @@ -673,48 +609,43 @@ 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]) { - 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]) { - radv_DestroyDescriptorSetLayout(radv_device_to_handle(device), - device->meta_state.blit2d.ds_layouts[src], - &device->meta_state.alloc); - } + radv_DestroyPipelineLayout(radv_device_to_handle(device), + state->blit2d.p_layouts[src], + &state->alloc); + radv_DestroyDescriptorSetLayout(radv_device_to_handle(device), + state->blit2d.ds_layouts[src], + &state->alloc); for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) { - if (device->meta_state.blit2d.pipelines[src][j]) { - radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit2d.pipelines[src][j], - &device->meta_state.alloc); - } + radv_DestroyPipeline(radv_device_to_handle(device), + state->blit2d.pipelines[src][j], + &state->alloc); } radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit2d.depth_only_pipeline[src], - &device->meta_state.alloc); + state->blit2d.depth_only_pipeline[src], + &state->alloc); radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit2d.stencil_only_pipeline[src], - &device->meta_state.alloc); + state->blit2d.stencil_only_pipeline[src], + &state->alloc); } } @@ -733,6 +664,10 @@ blit2d_init_color_pipeline(struct radv_device *device, 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"; @@ -746,7 +681,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); vi_create_info = &normal_vi_create_info; struct radv_shader_module vs = { @@ -769,37 +704,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_GENERAL, - .finalLayout = VK_IMAGE_LAYOUT_GENERAL, - }, - .subpassCount = 1, - .pSubpasses = &(VkSubpassDescription) { - .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, - .inputAttachmentCount = 0, - .colorAttachmentCount = 1, - .pColorAttachments = &(VkAttachmentReference) { - .attachment = 0, - .layout = VK_IMAGE_LAYOUT_GENERAL, + 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_GENERAL, - }, - .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 = 1, + .pPreserveAttachments = (uint32_t[]) { 0 }, + }, + .dependencyCount = 0, + }, &device->meta_state.alloc, &device->meta_state.blit2d.render_passes[fs_key][dst_layout]); + } } const VkGraphicsPipelineCreateInfo vk_pipeline_info = { @@ -858,7 +797,7 @@ 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], + .renderPass = device->meta_state.blit2d.render_passes[fs_key][0], .subpass = 0, }; @@ -892,6 +831,10 @@ blit2d_init_depth_only_pipeline(struct radv_device *device, 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"; @@ -904,7 +847,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); vi_create_info = &normal_vi_create_info; struct radv_shader_module vs = { @@ -927,34 +870,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 = 0, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = VK_IMAGE_LAYOUT_GENERAL, - .finalLayout = VK_IMAGE_LAYOUT_GENERAL, - }, - .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_GENERAL, - }, - .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 = 1, + .pPreserveAttachments = (uint32_t[]) { 0 }, + }, + .dependencyCount = 0, + }, &device->meta_state.alloc, &device->meta_state.blit2d.depth_only_rp[ds_layout]); + } } const VkGraphicsPipelineCreateInfo vk_pipeline_info = { @@ -1013,7 +959,7 @@ 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, + .renderPass = device->meta_state.blit2d.depth_only_rp[0], .subpass = 0, }; @@ -1047,6 +993,10 @@ blit2d_init_stencil_only_pipeline(struct radv_device *device, 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"; @@ -1059,7 +1009,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); vi_create_info = &normal_vi_create_info; struct radv_shader_module vs = { @@ -1082,34 +1032,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 = 0, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = VK_IMAGE_LAYOUT_GENERAL, - .finalLayout = VK_IMAGE_LAYOUT_GENERAL, - }, - .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_GENERAL, - }, - .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 = 1, + .pPreserveAttachments = (uint32_t[]) { 0 }, + }, + .dependencyCount = 0, + }, &device->meta_state.alloc, &device->meta_state.blit2d.stencil_only_rp[ds_layout]); + } } const VkGraphicsPipelineCreateInfo vk_pipeline_info = { @@ -1184,7 +1137,7 @@ 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, + .renderPass = device->meta_state.blit2d.stencil_only_rp[0], .subpass = 0, }; @@ -1209,6 +1162,8 @@ 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, @@ -1218,27 +1173,33 @@ static VkFormat pipeline_formats[] = { 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) { 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) ? 2 : 1; result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &(VkDescriptorSetLayoutCreateInfo) { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = 1, - .pBindings = (VkDescriptorSetLayoutBinding[]) { - { - .binding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - .pImmutableSamplers = NULL - }, + .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, + .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.ds_layouts[idx]); if (result != VK_SUCCESS) goto fail; @@ -1246,43 +1207,32 @@ 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], + .pSetLayouts = &device->meta_state.blit2d.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]); - if (result != VK_SUCCESS) - goto fail; - - result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), - &(VkDescriptorSetLayoutCreateInfo) { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .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]); + &device->meta_state.alloc, &device->meta_state.blit2d.p_layouts[idx]); if (result != VK_SUCCESS) goto fail; + return VK_SUCCESS; +fail: + return result; +} - const VkPushConstantRange push_constant_range = {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4}; - 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 = 1, - .pPushConstantRanges = &push_constant_range, - }, - &device->meta_state.alloc, &device->meta_state.blit2d.p_layouts[BLIT2D_SRC_TYPE_BUFFER]); - if (result != VK_SUCCESS) - goto fail; +VkResult +radv_device_init_meta_blit2d_state(struct radv_device *device) +{ + VkResult result; + bool create_3d = device->physical_device->rad_info.chip_class >= GFX9; for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) { + if (src == BLIT2D_SRC_TYPE_IMAGE_3D && !create_3d) + continue; + + result = meta_blit2d_create_pipe_layout(device, src); + if (result != VK_SUCCESS) + goto fail; + for (unsigned j = 0; j < ARRAY_SIZE(pipeline_formats); ++j) { result = blit2d_init_color_pipeline(device, src, pipeline_formats[j]); if (result != VK_SUCCESS)