| 2691 | } |
| 2692 | |
| 2693 | static void UpdateImageDescriptor(VulkanContext* context, HTexture texture_handle, ShaderResourceBinding* binding, VkDescriptorImageInfo& vk_image_info, VkWriteDescriptorSet& vk_write_desc_info) |
| 2694 | { |
| 2695 | VulkanTexture* texture = ResolveTextureDescriptorTexture(context, texture_handle, binding); |
| 2696 | |
| 2697 | if (texture->m_PendingUpload != INVALID_OPAQUE_HANDLE) |
| 2698 | { |
| 2699 | FenceResourcesToDestroy* pending_upload = context->m_FenceResourcesToDestroy.Get(texture->m_PendingUpload); |
| 2700 | |
| 2701 | // We need this resource now, so we have to wait for the fence to trigger. |
| 2702 | // If pending_upload is NULL, the request has already been satisfied so we don't have to do anything. |
| 2703 | if (pending_upload) |
| 2704 | { |
| 2705 | vkWaitForFences(context->m_LogicalDevice.m_Device, 1, &pending_upload->m_Fence, VK_TRUE, UINT64_MAX); |
| 2706 | |
| 2707 | // It's now safe to release the resources held by the fence |
| 2708 | DestroyFenceResourcesImmediately(context, texture->m_PendingUpload, pending_upload); |
| 2709 | } |
| 2710 | |
| 2711 | texture->m_PendingUpload = INVALID_OPAQUE_HANDLE; |
| 2712 | } |
| 2713 | |
| 2714 | TouchResource(context, texture); |
| 2715 | |
| 2716 | VkImageLayout image_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; |
| 2717 | VkSampler image_sampler = context->m_TextureSamplers[texture->m_TextureSamplerIndex].m_Sampler; |
| 2718 | VkImageView image_view = texture->m_Handle.m_ImageView; |
| 2719 | VkDescriptorType descriptor_type = TextureTypeToDescriptorType(binding->m_Type.m_ShaderType); |
| 2720 | |
| 2721 | if (binding->m_Type.m_ShaderType == ShaderDesc::SHADER_TYPE_RENDER_PASS_INPUT) |
| 2722 | { |
| 2723 | image_sampler = 0; |
| 2724 | } |
| 2725 | else if (binding->m_Type.m_ShaderType == ShaderDesc::SHADER_TYPE_IMAGE2D || binding->m_Type.m_ShaderType == ShaderDesc::SHADER_TYPE_UIMAGE2D) |
| 2726 | { |
| 2727 | image_layout = VK_IMAGE_LAYOUT_GENERAL; |
| 2728 | image_sampler = 0; |
| 2729 | } |
| 2730 | else if (binding->m_Type.m_ShaderType == ShaderDesc::SHADER_TYPE_SAMPLER) |
| 2731 | { |
| 2732 | image_layout = VK_IMAGE_LAYOUT_UNDEFINED; |
| 2733 | image_view = VK_NULL_HANDLE; |
| 2734 | } |
| 2735 | |
| 2736 | // If the image layout is in the wrong state, we need to transition it to the new layout, |
| 2737 | // otherwise its memory might be getting wrriten to while we are reading from it. |
| 2738 | // |
| 2739 | // TODO: We cannot use the in-frame command buffer here since it's illegal to use barriers while inside a render pass |
| 2740 | // So instead we have to use a temporary command buffer that only does the transition. |
| 2741 | // It would be better if we could decouple this somehow. Perhaps we can solve it by buffering all render events (with a render graph?) |
| 2742 | if (texture->m_ImageLayout[0] != image_layout && image_layout != VK_IMAGE_LAYOUT_UNDEFINED) |
| 2743 | { |
| 2744 | VkResult res = TransitionImageLayout(context->m_LogicalDevice.m_Device, |
| 2745 | context->m_LogicalDevice.m_CommandPool, |
| 2746 | context->m_LogicalDevice.m_GraphicsQueue, |
| 2747 | texture, |
| 2748 | VK_IMAGE_ASPECT_COLOR_BIT, |
| 2749 | image_layout); |
| 2750 | CHECK_VK_ERROR(res); |
no test coverage detected