1 // Copyright 2018 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef DAWNNATIVE_VULKAN_TEXTUREVK_H_
16 #define DAWNNATIVE_VULKAN_TEXTUREVK_H_
17 
18 #include "dawn_native/Texture.h"
19 
20 #include "common/vulkan_platform.h"
21 #include "dawn_native/PassResourceUsage.h"
22 #include "dawn_native/ResourceMemoryAllocation.h"
23 #include "dawn_native/vulkan/ExternalHandle.h"
24 #include "dawn_native/vulkan/external_memory/MemoryService.h"
25 
26 namespace dawn_native { namespace vulkan {
27 
28     struct CommandRecordingContext;
29     class Device;
30 
31     VkFormat VulkanImageFormat(const Device* device, wgpu::TextureFormat format);
32     VkImageUsageFlags VulkanImageUsage(wgpu::TextureUsage usage, const Format& format);
33     VkSampleCountFlagBits VulkanSampleCount(uint32_t sampleCount);
34 
35     MaybeError ValidateVulkanImageCanBeWrapped(const DeviceBase* device,
36                                                const TextureDescriptor* descriptor);
37 
38     bool IsSampleCountSupported(const dawn_native::vulkan::Device* device,
39                                 const VkImageCreateInfo& imageCreateInfo);
40 
41     class Texture final : public TextureBase {
42       public:
43         // Used to create a regular texture from a descriptor.
44         static ResultOrError<Ref<Texture>> Create(Device* device,
45                                                   const TextureDescriptor* descriptor,
46                                                   VkImageUsageFlags extraUsages = 0);
47 
48         // Creates a texture and initializes it with a VkImage that references an external memory
49         // object. Before the texture can be used, the VkDeviceMemory associated with the external
50         // image must be bound via Texture::BindExternalMemory.
51         static ResultOrError<Texture*> CreateFromExternal(
52             Device* device,
53             const ExternalImageDescriptorVk* descriptor,
54             const TextureDescriptor* textureDescriptor,
55             external_memory::Service* externalMemoryService);
56 
57         // Creates a texture that wraps a swapchain-allocated VkImage.
58         static Ref<Texture> CreateForSwapChain(Device* device,
59                                                const TextureDescriptor* descriptor,
60                                                VkImage nativeImage);
61 
62         VkImage GetHandle() const;
63         VkImageAspectFlags GetVkAspectMask(wgpu::TextureAspect aspect) const;
64 
65         // Transitions the texture to be used as `usage`, recording any necessary barrier in
66         // `commands`.
67         // TODO(cwallez@chromium.org): coalesce barriers and do them early when possible.
68         void TransitionFullUsage(CommandRecordingContext* recordingContext,
69                                  wgpu::TextureUsage usage);
70 
71         void TransitionUsageNow(CommandRecordingContext* recordingContext,
72                                 wgpu::TextureUsage usage,
73                                 const SubresourceRange& range);
74         void TransitionUsageAndGetResourceBarrier(wgpu::TextureUsage usage,
75                                                   const SubresourceRange& range,
76                                                   std::vector<VkImageMemoryBarrier>* imageBarriers,
77                                                   VkPipelineStageFlags* srcStages,
78                                                   VkPipelineStageFlags* dstStages);
79         void TransitionUsageForPass(CommandRecordingContext* recordingContext,
80                                     const PassTextureUsage& textureUsages,
81                                     std::vector<VkImageMemoryBarrier>* imageBarriers,
82                                     VkPipelineStageFlags* srcStages,
83                                     VkPipelineStageFlags* dstStages);
84 
85         void EnsureSubresourceContentInitialized(CommandRecordingContext* recordingContext,
86                                                  const SubresourceRange& range);
87 
88         VkImageLayout GetCurrentLayoutForSwapChain() const;
89 
90         // Binds externally allocated memory to the VkImage and on success, takes ownership of
91         // semaphores.
92         MaybeError BindExternalMemory(const ExternalImageDescriptorVk* descriptor,
93                                       VkSemaphore signalSemaphore,
94                                       VkDeviceMemory externalMemoryAllocation,
95                                       std::vector<VkSemaphore> waitSemaphores);
96 
97         MaybeError ExportExternalTexture(VkImageLayout desiredLayout,
98                                          VkSemaphore* signalSemaphore,
99                                          VkImageLayout* releasedOldLayout,
100                                          VkImageLayout* releasedNewLayout);
101 
102       private:
103         ~Texture() override;
104         using TextureBase::TextureBase;
105 
106         MaybeError InitializeAsInternalTexture(VkImageUsageFlags extraUsages);
107         MaybeError InitializeFromExternal(const ExternalImageDescriptorVk* descriptor,
108                                           external_memory::Service* externalMemoryService);
109         void InitializeForSwapChain(VkImage nativeImage);
110 
111         void DestroyImpl() override;
112         MaybeError ClearTexture(CommandRecordingContext* recordingContext,
113                                 const SubresourceRange& range,
114                                 TextureBase::ClearValue);
115 
116         void TweakTransitionForExternalUsage(CommandRecordingContext* recordingContext,
117                                              std::vector<VkImageMemoryBarrier>* barriers,
118                                              size_t transitionBarrierStart);
119         bool CanReuseWithoutBarrier(wgpu::TextureUsage lastUsage, wgpu::TextureUsage usage);
120 
121         VkImage mHandle = VK_NULL_HANDLE;
122         ResourceMemoryAllocation mMemoryAllocation;
123         VkDeviceMemory mExternalAllocation = VK_NULL_HANDLE;
124 
125         enum class ExternalState {
126             InternalOnly,
127             PendingAcquire,
128             Acquired,
129             Released
130         };
131         ExternalState mExternalState = ExternalState::InternalOnly;
132         ExternalState mLastExternalState = ExternalState::InternalOnly;
133 
134         VkImageLayout mPendingAcquireOldLayout;
135         VkImageLayout mPendingAcquireNewLayout;
136 
137         VkSemaphore mSignalSemaphore = VK_NULL_HANDLE;
138         std::vector<VkSemaphore> mWaitRequirements;
139 
140         bool mSameLastUsagesAcrossSubresources = true;
141 
142         // A usage of none will make sure the texture is transitioned before its first use as
143         // required by the Vulkan spec.
144         std::vector<wgpu::TextureUsage> mSubresourceLastUsages =
145             std::vector<wgpu::TextureUsage>(GetSubresourceCount(), wgpu::TextureUsage::None);
146     };
147 
148     class TextureView final : public TextureViewBase {
149       public:
150         static ResultOrError<TextureView*> Create(TextureBase* texture,
151                                                   const TextureViewDescriptor* descriptor);
152         VkImageView GetHandle() const;
153 
154       private:
155         ~TextureView() override;
156         using TextureViewBase::TextureViewBase;
157         MaybeError Initialize(const TextureViewDescriptor* descriptor);
158 
159         VkImageView mHandle = VK_NULL_HANDLE;
160     };
161 
162 }}  // namespace dawn_native::vulkan
163 
164 #endif  // DAWNNATIVE_VULKAN_TEXTUREVK_H_
165