diff --git a/src/imagination/vulkan/pvr_blit.c b/src/imagination/vulkan/pvr_blit.c index dfaf98e64d6..a70bf472606 100644 --- a/src/imagination/vulkan/pvr_blit.c +++ b/src/imagination/vulkan/pvr_blit.c @@ -1053,11 +1053,17 @@ pvr_copy_image_to_buffer_region(struct pvr_cmd_buffer *const cmd_buffer, VkFormat src_format = pvr_get_copy_format(image->vk.format); VkFormat dst_format; - /* Color and depth aspect copies can be done using an appropriate raw format. + /* Color and depth aspect copies can nearly all be done using an appropriate + * raw format. */ if (aspect_mask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)) { - src_format = pvr_get_raw_copy_format(src_format); - dst_format = src_format; + if (src_format == VK_FORMAT_D32_SFLOAT_S8_UINT) { + dst_format = VK_FORMAT_D32_SFLOAT; + } else { + src_format = pvr_get_raw_copy_format(src_format); + + dst_format = src_format; + } } else if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) { /* From the Vulkan spec: * @@ -1211,7 +1217,7 @@ void pvr_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, uint32_t flags = 0U; VkResult result; - if (image->vk.format == VK_FORMAT_D24_UNORM_S8_UINT && + if (vk_format_aspects(image->vk.format) == ds_aspect && pRanges[i].aspectMask != ds_aspect) { /* A depth or stencil blit to a packed_depth_stencil requires a merge * operation. diff --git a/src/imagination/vulkan/pvr_cmd_buffer.c b/src/imagination/vulkan/pvr_cmd_buffer.c index 6e6acf152ac..a766d4dbd03 100644 --- a/src/imagination/vulkan/pvr_cmd_buffer.c +++ b/src/imagination/vulkan/pvr_cmd_buffer.c @@ -752,11 +752,21 @@ pvr_load_op_constants_create_and_upload(struct pvr_cmd_buffer *cmd_buffer, for (uint32_t i = 0; i < ARRAY_SIZE(load_op->clears_loads_state.dest_vk_format); i++) { - if (load_op->clears_loads_state.dest_vk_format[i] == - VK_FORMAT_D32_SFLOAT) { + switch (load_op->clears_loads_state.dest_vk_format[i]) { + case VK_FORMAT_D16_UNORM: + case VK_FORMAT_X8_D24_UNORM_PACK32: + case VK_FORMAT_D32_SFLOAT: + case VK_FORMAT_D24_UNORM_S8_UINT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: has_depth_load = true; break; + + default: + break; } + + if (has_depth_load) + break; } has_depth_clear = load_op->clears_loads_state.depth_clear_to_reg != -1; @@ -1677,6 +1687,10 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info, job->ds.zls_format = ROGUE_CR_ZLS_FORMAT_TYPE_24BITINT; break; + case VK_FORMAT_D32_SFLOAT_S8_UINT: + job->ds.zls_format = ROGUE_CR_ZLS_FORMAT_TYPE_F64Z; + break; + default: UNREACHABLE("Unsupported depth stencil format"); } diff --git a/src/imagination/vulkan/pvr_job_render.c b/src/imagination/vulkan/pvr_job_render.c index 64213c941b8..43c5706c15e 100644 --- a/src/imagination/vulkan/pvr_job_render.c +++ b/src/imagination/vulkan/pvr_job_render.c @@ -1304,6 +1304,7 @@ static void pvr_frag_state_stream_init(struct pvr_render_ctx *ctx, */ switch (zload_format) { case ROGUE_CR_ZLS_FORMAT_TYPE_F32Z: + case ROGUE_CR_ZLS_FORMAT_TYPE_F64Z: value.value = fui(depth_clear); break; diff --git a/src/imagination/vulkan/pvr_job_transfer.c b/src/imagination/vulkan/pvr_job_transfer.c index 0ec4c5696e5..8939bd49e45 100644 --- a/src/imagination/vulkan/pvr_job_transfer.c +++ b/src/imagination/vulkan/pvr_job_transfer.c @@ -191,17 +191,33 @@ static VkResult pvr_pbe_src_format_pick_depth( const VkFormat dst_format, enum pvr_transfer_pbe_pixel_src *const src_format_out) { - if (dst_format != VK_FORMAT_D24_UNORM_S8_UINT) - return VK_ERROR_FORMAT_NOT_SUPPORTED; - - switch (src_format) { + switch (dst_format) { case VK_FORMAT_D24_UNORM_S8_UINT: - case VK_FORMAT_X8_D24_UNORM_PACK32: - *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D24S8_D24S8; + switch (src_format) { + case VK_FORMAT_D24_UNORM_S8_UINT: + case VK_FORMAT_X8_D24_UNORM_PACK32: + *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D24S8_D24S8; + break; + + case VK_FORMAT_D32_SFLOAT: + *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D32_D24S8; + break; + + default: + return VK_ERROR_FORMAT_NOT_SUPPORTED; + } break; - case VK_FORMAT_D32_SFLOAT: - *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D32_D24S8; + case VK_FORMAT_D32_SFLOAT_S8_UINT: + switch (src_format) { + case VK_FORMAT_D32_SFLOAT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: + *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D32S8_D32S8; + break; + + default: + return VK_ERROR_FORMAT_NOT_SUPPORTED; + } break; default: @@ -216,17 +232,46 @@ static VkResult pvr_pbe_src_format_pick_stencil( const VkFormat dst_format, enum pvr_transfer_pbe_pixel_src *const src_format_out) { - if ((src_format != VK_FORMAT_D24_UNORM_S8_UINT && - src_format != VK_FORMAT_S8_UINT) || - dst_format != VK_FORMAT_D24_UNORM_S8_UINT) { + switch (dst_format) { + case VK_FORMAT_D24_UNORM_S8_UINT: + switch (src_format) { + case VK_FORMAT_D24_UNORM_S8_UINT: + *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_D24S8_D24S8; + break; + + case VK_FORMAT_S8_UINT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: + *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_S8_D24S8; + break; + + default: + return VK_ERROR_FORMAT_NOT_SUPPORTED; + } + break; + + case VK_FORMAT_D32_SFLOAT_S8_UINT: + switch (src_format) { + case VK_FORMAT_S8_UINT: + *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_S8_D32S8; + break; + + case VK_FORMAT_D24_UNORM_S8_UINT: + *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_D24S8_D32S8; + break; + + case VK_FORMAT_D32_SFLOAT_S8_UINT: + *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_D32S8_D32S8; + break; + + default: + return VK_ERROR_FORMAT_NOT_SUPPORTED; + } + break; + + default: return VK_ERROR_FORMAT_NOT_SUPPORTED; } - if (src_format == VK_FORMAT_S8_UINT) - *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_S8_D24S8; - else - *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_D24S8_D24S8; - return VK_SUCCESS; } @@ -309,6 +354,11 @@ pvr_pbe_src_format_ds(const struct pvr_transfer_cmd_surface *src, break; + case VK_FORMAT_D32_SFLOAT_S8_UINT: + assert(src_format == VK_FORMAT_D32_SFLOAT_S8_UINT); + *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_RAW64; + break; + default: if (src_format == VK_FORMAT_D24_UNORM_S8_UINT) *src_format_out = PVR_TRANSFER_PBE_PIXEL_SRC_SWAP_LMSB; @@ -730,6 +780,10 @@ pvr_pbe_setup_codegen_defaults(const struct pvr_device_info *dev_info, format = VK_FORMAT_R32_UINT; break; + case VK_FORMAT_D32_SFLOAT_S8_UINT: + format = VK_FORMAT_R32G32_UINT; + break; + default: format = dst->vk_format; break; @@ -951,6 +1005,13 @@ static void pvr_pbe_setup_swizzle(const struct pvr_transfer_cmd *transfer_cmd, surf_params->swizzle[3U] = PIPE_SWIZZLE_0; break; + case VK_FORMAT_D32_SFLOAT_S8_UINT: + surf_params->swizzle[0U] = PIPE_SWIZZLE_X; + surf_params->swizzle[1U] = PIPE_SWIZZLE_Y; + surf_params->swizzle[2U] = PIPE_SWIZZLE_0; + surf_params->swizzle[3U] = PIPE_SWIZZLE_0; + break; + default: { const uint32_t red_width = vk_format_get_component_bits(dst->vk_format, @@ -1526,6 +1587,7 @@ static inline VkResult pvr_image_state_set_codegen_defaults( struct pvr_device *device, struct pvr_transfer_3d_state *state, const struct pvr_transfer_cmd_surface *surface, + VkFormat dst_vk_format, uint32_t load, uint64_t *mem_ptr) { @@ -1548,6 +1610,7 @@ static inline VkResult pvr_image_state_set_codegen_defaults( info.format = VK_FORMAT_R32G32_UINT; break; default: + info.format = surface->vk_format; break; } break; @@ -1593,15 +1656,53 @@ static inline VkResult pvr_image_state_set_codegen_defaults( } info.tex_state_type = PVR_TEXTURE_STATE_SAMPLE; - memcpy(info.swizzle, - pvr_get_format_swizzle(info.format), - sizeof(info.swizzle)); - if (surface->vk_format == VK_FORMAT_S8_UINT) { + if (surface->vk_format == VK_FORMAT_S8_UINT && + (dst_vk_format == VK_FORMAT_D24_UNORM_S8_UINT || + dst_vk_format == VK_FORMAT_S8_UINT)) { info.swizzle[0U] = PIPE_SWIZZLE_X; info.swizzle[1U] = PIPE_SWIZZLE_0; info.swizzle[2U] = PIPE_SWIZZLE_0; info.swizzle[3U] = PIPE_SWIZZLE_0; + } else if (surface->vk_format == VK_FORMAT_S8_UINT && + dst_vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT) { + info.swizzle[0U] = PIPE_SWIZZLE_X; + info.swizzle[1U] = PIPE_SWIZZLE_0; + info.swizzle[2U] = PIPE_SWIZZLE_0; + info.swizzle[3U] = PIPE_SWIZZLE_1; + } else if (surface->vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT) { + switch (dst_vk_format) { + case VK_FORMAT_S8_UINT: + info.swizzle[0U] = PIPE_SWIZZLE_Y; + info.swizzle[1U] = PIPE_SWIZZLE_0; + info.swizzle[2U] = PIPE_SWIZZLE_0; + info.swizzle[3U] = PIPE_SWIZZLE_0; + break; + + case VK_FORMAT_D24_UNORM_S8_UINT: + info.swizzle[0U] = PIPE_SWIZZLE_Y; + info.swizzle[1U] = PIPE_SWIZZLE_X; + info.swizzle[2U] = PIPE_SWIZZLE_0; + info.swizzle[3U] = PIPE_SWIZZLE_0; + break; + + case VK_FORMAT_D32_SFLOAT_S8_UINT: + info.swizzle[0U] = PIPE_SWIZZLE_X; + info.swizzle[1U] = PIPE_SWIZZLE_Y; + info.swizzle[2U] = PIPE_SWIZZLE_0; + info.swizzle[3U] = PIPE_SWIZZLE_0; + break; + + default: + memcpy(info.swizzle, + pvr_get_format_swizzle(info.format), + sizeof(info.swizzle)); + break; + } + } else { + memcpy(info.swizzle, + pvr_get_format_swizzle(info.format), + sizeof(info.swizzle)); } if (info.extent.depth > 0U) @@ -1638,6 +1739,7 @@ static VkResult pvr_image_state_for_surface( result = pvr_image_state_set_codegen_defaults(ctx->device, state, surface, + transfer_cmd->dst.vk_format, load, (uint64_t *)tex_state); if (result != VK_SUCCESS) @@ -2007,6 +2109,7 @@ static bool pvr_requires_usc_linear_filter(VkFormat format) case VK_FORMAT_D32_SFLOAT: case VK_FORMAT_D24_UNORM_S8_UINT: case VK_FORMAT_X8_D24_UNORM_PACK32: + case VK_FORMAT_D32_SFLOAT_S8_UINT: return true; default: return false; diff --git a/src/imagination/vulkan/pvr_pass.c b/src/imagination/vulkan/pvr_pass.c index ea1928ac420..e9e26b23324 100644 --- a/src/imagination/vulkan/pvr_pass.c +++ b/src/imagination/vulkan/pvr_pass.c @@ -284,8 +284,11 @@ pvr_subpass_load_op_init(struct pvr_device *device, case VK_ATTACHMENT_LOAD_OP_LOAD: assert(z_replicate < PVR_LOAD_OP_CLEARS_LOADS_MAX_RTS); load_op->clears_loads_state.rt_load_mask = BITFIELD_BIT(z_replicate); + + assert(subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED); load_op->clears_loads_state.dest_vk_format[z_replicate] = - VK_FORMAT_D32_SFLOAT; + pass->attachments[subpass->depth_stencil_attachment].vk_format; + break; case VK_ATTACHMENT_LOAD_OP_CLEAR: