X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_meta_blit.c;h=1f5f6ff739d730cff00991b7d97ea8e6eca02967;hb=258ebe79a0c2133e362035b76f3cf3243880926f;hp=803855a48f07bc9ef2e66b3c2e2178e338dc5266;hpb=b06568873d8a6dc6566c40fe6eb3bc33eef76098;p=mesa.git diff --git a/src/amd/vulkan/radv_meta_blit.c b/src/amd/vulkan/radv_meta_blit.c index 803855a48f0..1f5f6ff739d 100644 --- a/src/amd/vulkan/radv_meta_blit.c +++ b/src/amd/vulkan/radv_meta_blit.c @@ -38,25 +38,64 @@ 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_blit_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, - vec4, "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, vec4, "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 *src0_z = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_push_constant); + src0_z->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0)); + nir_intrinsic_set_base(src0_z, 16); + nir_intrinsic_set_range(src0_z, 4); + src0_z->num_components = 1; + nir_ssa_dest_init(&src0_z->instr, &src0_z->dest, 1, 32, "src0_z"); + nir_builder_instr_insert(&b, &src0_z->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 - src0_x, src0_y, src0_z */ + /* vertex 1 - src0_x, src1_y, src0_z*/ + /* vertex 2 - src1_x, src0_y, src0_z */ + /* 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[4]; + 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)); + comp[2] = &src0_z->dest.ssa; + comp[3] = nir_imm_float(&b, 1.0); + nir_ssa_def *out_tex_vec = nir_vec(&b, comp, 4); + nir_store_var(&b, tex_pos_out, out_tex_vec, 0xf); return b.shader; } @@ -70,7 +109,7 @@ build_nir_copy_fragment_shader(enum glsl_sampler_dim tex_dim) nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL); sprintf(shader_name, "meta_blit_fs.%d", tex_dim); - b.shader->info->name = ralloc_strdup(b.shader, shader_name); + b.shader->info.name = ralloc_strdup(b.shader, shader_name); nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec4, "v_tex_pos"); @@ -124,7 +163,7 @@ build_nir_copy_fragment_shader_depth(enum glsl_sampler_dim tex_dim) nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL); sprintf(shader_name, "meta_blit_depth_fs.%d", tex_dim); - b.shader->info->name = ralloc_strdup(b.shader, shader_name); + b.shader->info.name = ralloc_strdup(b.shader, shader_name); nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec4, "v_tex_pos"); @@ -178,7 +217,7 @@ build_nir_copy_fragment_shader_stencil(enum glsl_sampler_dim tex_dim) nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL); sprintf(shader_name, "meta_blit_stencil_fs.%d", tex_dim); - b.shader->info->name = ralloc_strdup(b.shader, shader_name); + b.shader->info.name = ralloc_strdup(b.shader, shader_name); nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec4, "v_tex_pos"); @@ -226,75 +265,38 @@ static void meta_emit_blit(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image, struct radv_image_view *src_iview, - VkOffset3D src_offset, - VkExtent3D src_extent, + VkImageLayout src_image_layout, + VkOffset3D src_offset_0, + VkOffset3D src_offset_1, struct radv_image *dest_image, struct radv_image_view *dest_iview, - VkOffset3D dest_offset, - VkExtent3D dest_extent, + VkImageLayout dest_image_layout, + VkOffset2D dest_offset_0, + VkOffset2D dest_offset_1, + VkRect2D dest_box, VkFilter blit_filter) { struct radv_device *device = cmd_buffer->device; - unsigned offset = 0; - struct blit_vb_data { - float pos[2]; - float tex_coord[3]; - } vb_data[3]; - - assert(src_image->samples == dest_image->samples); - unsigned vb_size = 3 * sizeof(*vb_data); - vb_data[0] = (struct blit_vb_data) { - .pos = { - dest_offset.x, - dest_offset.y, - }, - .tex_coord = { - (float)(src_offset.x) / (float)src_iview->extent.width, - (float)(src_offset.y) / (float)src_iview->extent.height, - (float)src_offset.z / (float)src_iview->extent.depth, - }, - }; - - vb_data[1] = (struct blit_vb_data) { - .pos = { - dest_offset.x, - dest_offset.y + dest_extent.height, - }, - .tex_coord = { - (float)src_offset.x / (float)src_iview->extent.width, - (float)(src_offset.y + src_extent.height) / - (float)src_iview->extent.height, - (float)src_offset.z / (float)src_iview->extent.depth, - }, - }; - - vb_data[2] = (struct blit_vb_data) { - .pos = { - dest_offset.x + dest_extent.width, - dest_offset.y, - }, - .tex_coord = { - (float)(src_offset.x + src_extent.width) / (float)src_iview->extent.width, - (float)src_offset.y / (float)src_iview->extent.height, - (float)src_offset.z / (float)src_iview->extent.depth, - }, - }; - 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, + uint32_t src_width = radv_minify(src_iview->image->info.width, src_iview->base_mip); + uint32_t src_height = radv_minify(src_iview->image->info.height, src_iview->base_mip); + uint32_t src_depth = radv_minify(src_iview->image->info.depth, src_iview->base_mip); + uint32_t dst_width = radv_minify(dest_iview->image->info.width, dest_iview->base_mip); + uint32_t dst_height = radv_minify(dest_iview->image->info.height, dest_iview->base_mip); + + assert(src_image->info.samples == dest_image->info.samples); + + float vertex_push_constants[5] = { + (float)src_offset_0.x / (float)src_width, + (float)src_offset_0.y / (float)src_height, + (float)src_offset_1.x / (float)src_width, + (float)src_offset_1.y / (float)src_height, + (float)src_offset_0.z / (float)src_depth, }; - radv_CmdBindVertexBuffers(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, - (VkBuffer[]) { - radv_buffer_to_handle(&vertex_buffer) - }, - (VkDeviceSize[]) { - 0, - }); + radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), + device->meta_state.blit.pipeline_layout, + VK_SHADER_STAGE_VERTEX_BIT, 0, 20, + vertex_push_constants); VkSampler sampler; radv_CreateSampler(radv_device_to_handle(device), @@ -307,31 +309,6 @@ meta_emit_blit(struct radv_cmd_buffer *cmd_buffer, .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, }, &cmd_buffer->pool->alloc, &sampler); - VkDescriptorSet set; - radv_temp_descriptor_set_create(cmd_buffer->device, cmd_buffer, - device->meta_state.blit.ds_layout, - &set); - - radv_UpdateDescriptorSets(radv_device_to_handle(device), - 1, /* writeCount */ - (VkWriteDescriptorSet[]) { - { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = set, - .dstBinding = 0, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .pImageInfo = (VkDescriptorImageInfo[]) { - { - .sampler = sampler, - .imageView = radv_image_view_to_handle(src_iview), - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - }, - } - } - }, 0, NULL); - VkFramebuffer fb; radv_CreateFramebuffer(radv_device_to_handle(device), &(VkFramebufferCreateInfo) { @@ -340,8 +317,8 @@ meta_emit_blit(struct radv_cmd_buffer *cmd_buffer, .pAttachments = (VkImageView[]) { radv_image_view_to_handle(dest_iview), }, - .width = dest_iview->extent.width, - .height = dest_iview->extent.height, + .width = dst_width, + .height = dst_height, .layers = 1, }, &cmd_buffer->pool->alloc, &fb); VkPipeline pipeline; @@ -355,8 +332,8 @@ meta_emit_blit(struct radv_cmd_buffer *cmd_buffer, .renderPass = device->meta_state.blit.render_pass[fs_key], .framebuffer = fb, .renderArea = { - .offset = { dest_offset.x, dest_offset.y }, - .extent = { dest_extent.width, dest_extent.height }, + .offset = { dest_box.offset.x, dest_box.offset.y }, + .extent = { dest_box.extent.width, dest_box.extent.height }, }, .clearValueCount = 0, .pClearValues = NULL, @@ -376,15 +353,16 @@ meta_emit_blit(struct radv_cmd_buffer *cmd_buffer, } break; } - case VK_IMAGE_ASPECT_DEPTH_BIT: + case VK_IMAGE_ASPECT_DEPTH_BIT: { + enum radv_blit_ds_layout ds_layout = radv_meta_blit_ds_to_type(dest_image_layout); radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer), &(VkRenderPassBeginInfo) { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = device->meta_state.blit.depth_only_rp, + .renderPass = device->meta_state.blit.depth_only_rp[ds_layout], .framebuffer = fb, .renderArea = { - .offset = { dest_offset.x, dest_offset.y }, - .extent = { dest_extent.width, dest_extent.height }, + .offset = { dest_box.offset.x, dest_box.offset.y }, + .extent = { dest_box.extent.width, dest_box.extent.height }, }, .clearValueCount = 0, .pClearValues = NULL, @@ -403,16 +381,18 @@ meta_emit_blit(struct radv_cmd_buffer *cmd_buffer, unreachable(!"bad VkImageType"); } break; - case VK_IMAGE_ASPECT_STENCIL_BIT: + } + case VK_IMAGE_ASPECT_STENCIL_BIT: { + enum radv_blit_ds_layout ds_layout = radv_meta_blit_ds_to_type(dest_image_layout); radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer), &(VkRenderPassBeginInfo) { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = device->meta_state.blit.stencil_only_rp, + .renderPass = device->meta_state.blit.stencil_only_rp[ds_layout], .framebuffer = fb, .renderArea = { - .offset = { dest_offset.x, dest_offset.y }, - .extent = { dest_extent.width, dest_extent.height }, - }, + .offset = { dest_box.offset.x, dest_box.offset.y }, + .extent = { dest_box.extent.width, dest_box.extent.height }, + }, .clearValueCount = 0, .pClearValues = NULL, }, VK_SUBPASS_CONTENTS_INLINE); @@ -430,19 +410,51 @@ meta_emit_blit(struct radv_cmd_buffer *cmd_buffer, unreachable(!"bad VkImageType"); } break; + } default: unreachable(!"bad VkImageType"); } - 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_CmdBindDescriptorSets(radv_cmd_buffer_to_handle(cmd_buffer), - VK_PIPELINE_BIND_POINT_GRAPHICS, - device->meta_state.blit.pipeline_layout, 0, 1, - &set, 0, NULL); + radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), + VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + + radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + device->meta_state.blit.pipeline_layout, + 0, /* set */ + 1, /* descriptorWriteCount */ + (VkWriteDescriptorSet[]) { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = (VkDescriptorImageInfo[]) { + { + .sampler = sampler, + .imageView = radv_image_view_to_handle(src_iview), + .imageLayout = VK_IMAGE_LAYOUT_GENERAL, + }, + } + } + }); + + radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) { + .x = dest_offset_0.x, + .y = dest_offset_0.y, + .width = dest_offset_1.x - dest_offset_0.x, + .height = dest_offset_1.y - dest_offset_0.y, + .minDepth = 0.0f, + .maxDepth = 1.0f + }); + + radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkRect2D) { + .offset = (VkOffset2D) { MIN2(dest_offset_0.x, dest_offset_1.x), MIN2(dest_offset_0.y, dest_offset_1.y) }, + .extent = (VkExtent2D) { + abs(dest_offset_1.x - dest_offset_0.x), + abs(dest_offset_1.y - dest_offset_0.y) + }, + }); radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0); @@ -454,13 +466,32 @@ meta_emit_blit(struct radv_cmd_buffer *cmd_buffer, /* TODO: above comment is not valid for at least descriptor sets/pools, * as we may not free them till after execution finishes. Check others. */ - radv_temp_descriptor_set_destroy(cmd_buffer->device, set); radv_DestroySampler(radv_device_to_handle(device), sampler, &cmd_buffer->pool->alloc); radv_DestroyFramebuffer(radv_device_to_handle(device), fb, &cmd_buffer->pool->alloc); } +static bool +flip_coords(unsigned *src0, unsigned *src1, unsigned *dst0, unsigned *dst1) +{ + bool flip = false; + if (*src0 > *src1) { + unsigned tmp = *src0; + *src0 = *src1; + *src1 = tmp; + flip = !flip; + } + + if (*dst0 > *dst1) { + unsigned tmp = *dst0; + *dst0 = *dst1; + *dst1 = tmp; + flip = !flip; + } + return flip; +} + void radv_CmdBlitImage( VkCommandBuffer commandBuffer, VkImage srcImage, @@ -482,75 +513,89 @@ void radv_CmdBlitImage( * vkCmdBlitImage must not be used for multisampled source or * destination images. Use vkCmdResolveImage for this purpose. */ - assert(src_image->samples == 1); - assert(dest_image->samples == 1); + assert(src_image->info.samples == 1); + assert(dest_image->info.samples == 1); - radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer); + radv_meta_save(&saved_state, cmd_buffer, + RADV_META_SAVE_GRAPHICS_PIPELINE | + RADV_META_SAVE_CONSTANTS | + RADV_META_SAVE_DESCRIPTORS); for (unsigned r = 0; r < regionCount; r++) { const VkImageSubresourceLayers *src_res = &pRegions[r].srcSubresource; const VkImageSubresourceLayers *dst_res = &pRegions[r].dstSubresource; - struct radv_image_view src_iview; - radv_image_view_init(&src_iview, cmd_buffer->device, - &(VkImageViewCreateInfo) { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .image = srcImage, - .viewType = radv_meta_get_view_type(src_image), - .format = src_image->vk_format, - .subresourceRange = { - .aspectMask = src_res->aspectMask, - .baseMipLevel = src_res->mipLevel, - .levelCount = 1, - .baseArrayLayer = src_res->baseArrayLayer, - .layerCount = 1 - }, - }, - cmd_buffer, VK_IMAGE_USAGE_SAMPLED_BIT); - - if (pRegions[r].dstOffsets[1].x < pRegions[r].dstOffsets[0].x || - pRegions[r].dstOffsets[1].y < pRegions[r].dstOffsets[0].y || - pRegions[r].srcOffsets[1].x < pRegions[r].srcOffsets[0].x || - pRegions[r].srcOffsets[1].y < pRegions[r].srcOffsets[0].y) - radv_finishme("FINISHME: Allow flipping in blits"); - - const VkExtent3D dest_extent = { - .width = pRegions[r].dstOffsets[1].x - pRegions[r].dstOffsets[0].x, - .height = pRegions[r].dstOffsets[1].y - pRegions[r].dstOffsets[0].y, - .depth = 1, - }; - - const VkExtent3D src_extent = { - .width = pRegions[r].srcOffsets[1].x - pRegions[r].srcOffsets[0].x, - .height = pRegions[r].srcOffsets[1].y - pRegions[r].srcOffsets[0].y, - .depth = pRegions[r].srcOffsets[1].z - pRegions[r].srcOffsets[0].z, - }; + unsigned dst_start, dst_end; + if (dest_image->type == VK_IMAGE_TYPE_3D) { + assert(dst_res->baseArrayLayer == 0); + dst_start = pRegions[r].dstOffsets[0].z; + dst_end = pRegions[r].dstOffsets[1].z; + } else { + dst_start = dst_res->baseArrayLayer; + dst_end = dst_start + dst_res->layerCount; + } - if (src_res->layerCount > 1) - radv_finishme("FINISHME: copy multiple array layers"); + unsigned src_start, src_end; + if (src_image->type == VK_IMAGE_TYPE_3D) { + assert(src_res->baseArrayLayer == 0); + src_start = pRegions[r].srcOffsets[0].z; + src_end = pRegions[r].srcOffsets[1].z; + } else { + src_start = src_res->baseArrayLayer; + src_end = src_start + src_res->layerCount; + } - struct radv_image_view dest_iview; - unsigned usage; - if (dst_res->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) - usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - else - usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + bool flip_z = flip_coords(&src_start, &src_end, &dst_start, &dst_end); + float src_z_step = (float)(src_end + 1 - src_start) / + (float)(dst_end + 1 - dst_start); - for (unsigned i = pRegions[r].dstOffsets[0].z; i < pRegions[r].dstOffsets[1].z; i++) { + if (flip_z) { + src_start = src_end; + src_z_step *= -1; + } - const VkOffset3D dest_offset = { - .x = pRegions[r].dstOffsets[0].x, - .y = pRegions[r].dstOffsets[0].y, - .z = i, + unsigned src_x0 = pRegions[r].srcOffsets[0].x; + unsigned src_x1 = pRegions[r].srcOffsets[1].x; + unsigned dst_x0 = pRegions[r].dstOffsets[0].x; + unsigned dst_x1 = pRegions[r].dstOffsets[1].x; + + unsigned src_y0 = pRegions[r].srcOffsets[0].y; + unsigned src_y1 = pRegions[r].srcOffsets[1].y; + unsigned dst_y0 = pRegions[r].dstOffsets[0].y; + unsigned dst_y1 = pRegions[r].dstOffsets[1].y; + + VkRect2D dest_box; + dest_box.offset.x = MIN2(dst_x0, dst_x1); + dest_box.offset.y = MIN2(dst_y0, dst_y1); + dest_box.extent.width = abs(dst_x1 - dst_x0); + dest_box.extent.height = abs(dst_y1 - dst_y0); + + const unsigned num_layers = dst_end - dst_start; + for (unsigned i = 0; i < num_layers; i++) { + struct radv_image_view dest_iview, src_iview; + + const VkOffset2D dest_offset_0 = { + .x = dst_x0, + .y = dst_y0, }; - VkOffset3D src_offset = { - .x = pRegions[r].srcOffsets[0].x, - .y = pRegions[r].srcOffsets[0].y, - .z = i, + const VkOffset2D dest_offset_1 = { + .x = dst_x1, + .y = dst_y1, }; - const uint32_t dest_array_slice = - radv_meta_get_iview_layer(dest_image, dst_res, - &dest_offset); + VkOffset3D src_offset_0 = { + .x = src_x0, + .y = src_y0, + .z = src_start + i * src_z_step, + }; + VkOffset3D src_offset_1 = { + .x = src_x1, + .y = src_y1, + .z = src_start + i * src_z_step, + }; + const uint32_t dest_array_slice = dst_start + i; + + /* 3D images have just 1 layer */ + const uint32_t src_array_slice = src_image->type == VK_IMAGE_TYPE_3D ? 0 : src_start + i; radv_image_view_init(&dest_iview, cmd_buffer->device, &(VkImageViewCreateInfo) { @@ -565,13 +610,27 @@ void radv_CmdBlitImage( .baseArrayLayer = dest_array_slice, .layerCount = 1 }, - }, - cmd_buffer, usage); + }); + radv_image_view_init(&src_iview, cmd_buffer->device, + &(VkImageViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = srcImage, + .viewType = radv_meta_get_view_type(src_image), + .format = src_image->vk_format, + .subresourceRange = { + .aspectMask = src_res->aspectMask, + .baseMipLevel = src_res->mipLevel, + .levelCount = 1, + .baseArrayLayer = src_array_slice, + .layerCount = 1 + }, + }); meta_emit_blit(cmd_buffer, - src_image, &src_iview, - src_offset, src_extent, - dest_image, &dest_iview, - dest_offset, dest_extent, + src_image, &src_iview, srcImageLayout, + src_offset_0, src_offset_1, + dest_image, &dest_iview, destImageLayout, + dest_offset_0, dest_offset_1, + dest_box, filter); } } @@ -582,71 +641,60 @@ void radv_CmdBlitImage( void radv_device_finish_meta_blit_state(struct radv_device *device) { - for (unsigned i = 0; i < NUM_META_FS_KEYS; ++i) { - if (device->meta_state.blit.render_pass[i]) - radv_DestroyRenderPass(radv_device_to_handle(device), - device->meta_state.blit.render_pass[i], - &device->meta_state.alloc); - if (device->meta_state.blit.pipeline_1d_src[i]) - radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit.pipeline_1d_src[i], - &device->meta_state.alloc); - if (device->meta_state.blit.pipeline_2d_src[i]) - radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit.pipeline_2d_src[i], - &device->meta_state.alloc); - if (device->meta_state.blit.pipeline_3d_src[i]) - radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit.pipeline_3d_src[i], - &device->meta_state.alloc); - } + struct radv_meta_state *state = &device->meta_state; - if (device->meta_state.blit.depth_only_rp) + for (unsigned i = 0; i < NUM_META_FS_KEYS; ++i) { radv_DestroyRenderPass(radv_device_to_handle(device), - device->meta_state.blit.depth_only_rp, - &device->meta_state.alloc); - if (device->meta_state.blit.depth_only_1d_pipeline) + state->blit.render_pass[i], + &state->alloc); radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit.depth_only_1d_pipeline, - &device->meta_state.alloc); - if (device->meta_state.blit.depth_only_2d_pipeline) + state->blit.pipeline_1d_src[i], + &state->alloc); radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit.depth_only_2d_pipeline, - &device->meta_state.alloc); - if (device->meta_state.blit.depth_only_3d_pipeline) + state->blit.pipeline_2d_src[i], + &state->alloc); radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit.depth_only_3d_pipeline, - &device->meta_state.alloc); - if (device->meta_state.blit.stencil_only_rp) + state->blit.pipeline_3d_src[i], + &state->alloc); + } + + for (enum radv_blit_ds_layout i = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; i < RADV_BLIT_DS_LAYOUT_COUNT; i++) { radv_DestroyRenderPass(radv_device_to_handle(device), - device->meta_state.blit.stencil_only_rp, - &device->meta_state.alloc); - if (device->meta_state.blit.stencil_only_1d_pipeline) - radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit.stencil_only_1d_pipeline, - &device->meta_state.alloc); - if (device->meta_state.blit.stencil_only_2d_pipeline) - radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit.stencil_only_2d_pipeline, - &device->meta_state.alloc); - if (device->meta_state.blit.stencil_only_3d_pipeline) - radv_DestroyPipeline(radv_device_to_handle(device), - device->meta_state.blit.stencil_only_3d_pipeline, - &device->meta_state.alloc); - if (device->meta_state.blit.pipeline_layout) - radv_DestroyPipelineLayout(radv_device_to_handle(device), - device->meta_state.blit.pipeline_layout, - &device->meta_state.alloc); - if (device->meta_state.blit.ds_layout) - radv_DestroyDescriptorSetLayout(radv_device_to_handle(device), - device->meta_state.blit.ds_layout, - &device->meta_state.alloc); + state->blit.depth_only_rp[i], &state->alloc); + radv_DestroyRenderPass(radv_device_to_handle(device), + state->blit.stencil_only_rp[i], &state->alloc); + } + + radv_DestroyPipeline(radv_device_to_handle(device), + state->blit.depth_only_1d_pipeline, &state->alloc); + radv_DestroyPipeline(radv_device_to_handle(device), + state->blit.depth_only_2d_pipeline, &state->alloc); + radv_DestroyPipeline(radv_device_to_handle(device), + state->blit.depth_only_3d_pipeline, &state->alloc); + + radv_DestroyPipeline(radv_device_to_handle(device), + state->blit.stencil_only_1d_pipeline, + &state->alloc); + radv_DestroyPipeline(radv_device_to_handle(device), + state->blit.stencil_only_2d_pipeline, + &state->alloc); + radv_DestroyPipeline(radv_device_to_handle(device), + state->blit.stencil_only_3d_pipeline, + &state->alloc); + + + radv_DestroyPipelineLayout(radv_device_to_handle(device), + state->blit.pipeline_layout, &state->alloc); + radv_DestroyDescriptorSetLayout(radv_device_to_handle(device), + state->blit.ds_layout, &state->alloc); } 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, @@ -704,31 +752,8 @@ radv_device_init_meta_blit_color(struct radv_device *device, VkPipelineVertexInputStateCreateInfo vi_create_info = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 1, - .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) { - { - .binding = 0, - .stride = 5 * 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_R32G32B32_SFLOAT, - .offset = 8 - } - } + .vertexBindingDescriptionCount = 0, + .vertexAttributeDescriptionCount = 0, }; VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = { @@ -759,8 +784,8 @@ radv_device_init_meta_blit_color(struct radv_device *device, }, .pViewportState = &(VkPipelineViewportStateCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .viewportCount = 0, - .scissorCount = 0, + .viewportCount = 1, + .scissorCount = 1, }, .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, @@ -788,8 +813,10 @@ radv_device_init_meta_blit_color(struct radv_device *device, }, .pDynamicState = &(VkPipelineDynamicStateCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - .dynamicStateCount = 2, + .dynamicStateCount = 4, .pDynamicStates = (VkDynamicState[]) { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_BLEND_CONSTANTS, }, @@ -849,63 +876,43 @@ radv_device_init_meta_blit_depth(struct radv_device *device, fs_2d.nir = build_nir_copy_fragment_shader_depth(GLSL_SAMPLER_DIM_2D); fs_3d.nir = build_nir_copy_fragment_shader_depth(GLSL_SAMPLER_DIM_3D); - 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++) { + 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, + .format = VK_FORMAT_D32_SFLOAT, + .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = layout, + .finalLayout = layout, }, - .preserveAttachmentCount = 1, - .pPreserveAttachments = (uint32_t[]) { 0 }, - }, - .dependencyCount = 0, - }, &device->meta_state.alloc, &device->meta_state.blit.depth_only_rp); - if (result != VK_SUCCESS) - goto fail; + .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.blit.depth_only_rp[ds_layout]); + if (result != VK_SUCCESS) + goto fail; + } VkPipelineVertexInputStateCreateInfo vi_create_info = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 1, - .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) { - { - .binding = 0, - .stride = 5 * 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_R32G32B32_SFLOAT, - .offset = 8 - } - } + .vertexBindingDescriptionCount = 0, + .vertexAttributeDescriptionCount = 0, }; VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = { @@ -936,8 +943,8 @@ radv_device_init_meta_blit_depth(struct radv_device *device, }, .pViewportState = &(VkPipelineViewportStateCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .viewportCount = 0, - .scissorCount = 0, + .viewportCount = 1, + .scissorCount = 1, }, .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, @@ -965,8 +972,10 @@ radv_device_init_meta_blit_depth(struct radv_device *device, }, .pDynamicState = &(VkPipelineDynamicStateCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - .dynamicStateCount = 7, + .dynamicStateCount = 9, .pDynamicStates = (VkDynamicState[]) { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS, @@ -978,7 +987,7 @@ radv_device_init_meta_blit_depth(struct radv_device *device, }, .flags = 0, .layout = device->meta_state.blit.pipeline_layout, - .renderPass = device->meta_state.blit.depth_only_rp, + .renderPass = device->meta_state.blit.depth_only_rp[0], .subpass = 0, }; @@ -1028,63 +1037,43 @@ radv_device_init_meta_blit_stencil(struct radv_device *device, fs_2d.nir = build_nir_copy_fragment_shader_stencil(GLSL_SAMPLER_DIM_2D); fs_3d.nir = build_nir_copy_fragment_shader_stencil(GLSL_SAMPLER_DIM_3D); - 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++) { + 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, - }, + .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 = VK_IMAGE_LAYOUT_GENERAL, + .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 }, }, - .preserveAttachmentCount = 1, - .pPreserveAttachments = (uint32_t[]) { 0 }, - }, - .dependencyCount = 0, - }, &device->meta_state.alloc, &device->meta_state.blit.stencil_only_rp); + .dependencyCount = 0, + }, &device->meta_state.alloc, &device->meta_state.blit.stencil_only_rp[ds_layout]); + } if (result != VK_SUCCESS) goto fail; VkPipelineVertexInputStateCreateInfo vi_create_info = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 1, - .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) { - { - .binding = 0, - .stride = 5 * 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_R32G32B32_SFLOAT, - .offset = 8 - } - } + .vertexBindingDescriptionCount = 0, + .vertexAttributeDescriptionCount = 0, }; VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = { @@ -1115,8 +1104,8 @@ radv_device_init_meta_blit_stencil(struct radv_device *device, }, .pViewportState = &(VkPipelineViewportStateCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .viewportCount = 0, - .scissorCount = 0, + .viewportCount = 1, + .scissorCount = 1, }, .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, @@ -1161,11 +1150,12 @@ radv_device_init_meta_blit_stencil(struct radv_device *device, }, .depthCompareOp = VK_COMPARE_OP_ALWAYS, }, - .pDynamicState = &(VkPipelineDynamicStateCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - .dynamicStateCount = 4, + .dynamicStateCount = 6, .pDynamicStates = (VkDynamicState[]) { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS, @@ -1174,7 +1164,7 @@ radv_device_init_meta_blit_stencil(struct radv_device *device, }, .flags = 0, .layout = device->meta_state.blit.pipeline_layout, - .renderPass = device->meta_state.blit.stencil_only_rp, + .renderPass = device->meta_state.blit.stencil_only_rp[0], .subpass = 0, }; @@ -1206,6 +1196,7 @@ radv_device_init_meta_blit_stencil(struct radv_device *device, if (result != VK_SUCCESS) goto fail; + fail: ralloc_free(fs_1d.nir); ralloc_free(fs_2d.nir); @@ -1218,10 +1209,10 @@ radv_device_init_meta_blit_state(struct radv_device *device) { VkResult result; struct radv_shader_module vs = {0}; - zero(device->meta_state.blit); VkDescriptorSetLayoutCreateInfo ds_layout_info = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, .bindingCount = 1, .pBindings = (VkDescriptorSetLayoutBinding[]) { { @@ -1240,11 +1231,15 @@ radv_device_init_meta_blit_state(struct radv_device *device) if (result != VK_SUCCESS) goto fail; + const VkPushConstantRange push_constant_range = {VK_SHADER_STAGE_VERTEX_BIT, 0, 20}; + result = radv_CreatePipelineLayout(radv_device_to_handle(device), &(VkPipelineLayoutCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .setLayoutCount = 1, .pSetLayouts = &device->meta_state.blit.ds_layout, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &push_constant_range, }, &device->meta_state.alloc, &device->meta_state.blit.pipeline_layout); if (result != VK_SUCCESS) @@ -1261,12 +1256,10 @@ radv_device_init_meta_blit_state(struct radv_device *device) goto fail; result = radv_device_init_meta_blit_stencil(device, &vs); - if (result != VK_SUCCESS) - goto fail; - return VK_SUCCESS; fail: ralloc_free(vs.nir); - radv_device_finish_meta_blit_state(device); + if (result != VK_SUCCESS) + radv_device_finish_meta_blit_state(device); return result; }