• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     class Texture;
31 
32     VkFormat VulkanImageFormat(const Device* device, wgpu::TextureFormat format);
33     VkImageUsageFlags VulkanImageUsage(wgpu::TextureUsage usage, const Format& format);
34     VkImageLayout VulkanImageLayout(const Texture* texture, wgpu::TextureUsage usage);
35     VkSampleCountFlagBits VulkanSampleCount(uint32_t sampleCount);
36 
37     MaybeError ValidateVulkanImageCanBeWrapped(const DeviceBase* device,
38                                                const TextureDescriptor* descriptor);
39 
40     bool IsSampleCountSupported(const dawn_native::vulkan::Device* device,
41                                 const VkImageCreateInfo& imageCreateInfo);
42 
43     class Texture final : public TextureBase {
44       public:
45         // Used to create a regular texture from a descriptor.
46         static ResultOrError<Ref<Texture>> Create(Device* device,
47                                                   const TextureDescriptor* descriptor,
48                                                   VkImageUsageFlags extraUsages = 0);
49 
50         // Creates a texture and initializes it with a VkImage that references an external memory
51         // object. Before the texture can be used, the VkDeviceMemory associated with the external
52         // image must be bound via Texture::BindExternalMemory.
53         static ResultOrError<Texture*> CreateFromExternal(
54             Device* device,
55             const ExternalImageDescriptorVk* descriptor,
56             const TextureDescriptor* textureDescriptor,
57             external_memory::Service* externalMemoryService);
58 
59         // Creates a texture that wraps a swapchain-allocated VkImage.
60         static Ref<Texture> CreateForSwapChain(Device* device,
61                                                const TextureDescriptor* descriptor,
62                                                VkImage nativeImage);
63 
64         VkImage GetHandle() const;
65         VkImageAspectFlags GetVkAspectMask(wgpu::TextureAspect aspect) const;
66 
67         // Transitions the texture to be used as `usage`, recording any necessary barrier in
68         // `commands`.
69         // TODO(crbug.com/dawn/851): coalesce barriers and do them early when possible.
70         void TransitionUsageNow(CommandRecordingContext* recordingContext,
71                                 wgpu::TextureUsage usage,
72                                 const SubresourceRange& range);
73         void TransitionUsageForPass(CommandRecordingContext* recordingContext,
74                                     const TextureSubresourceUsage& textureUsages,
75                                     std::vector<VkImageMemoryBarrier>* imageBarriers,
76                                     VkPipelineStageFlags* srcStages,
77                                     VkPipelineStageFlags* dstStages);
78 
79         void EnsureSubresourceContentInitialized(CommandRecordingContext* recordingContext,
80                                                  const SubresourceRange& range);
81 
82         VkImageLayout GetCurrentLayoutForSwapChain() const;
83 
84         // Binds externally allocated memory to the VkImage and on success, takes ownership of
85         // semaphores.
86         MaybeError BindExternalMemory(const ExternalImageDescriptorVk* descriptor,
87                                       VkSemaphore signalSemaphore,
88                                       VkDeviceMemory externalMemoryAllocation,
89                                       std::vector<VkSemaphore> waitSemaphores);
90 
91         MaybeError ExportExternalTexture(VkImageLayout desiredLayout,
92                                          VkSemaphore* signalSemaphore,
93                                          VkImageLayout* releasedOldLayout,
94                                          VkImageLayout* releasedNewLayout);
95 
96         void SetLabelHelper(const char* prefix);
97 
98         // Dawn API
99         void SetLabelImpl() override;
100 
101       private:
102         ~Texture() override;
103         Texture(Device* device, const TextureDescriptor* descriptor, TextureState state);
104 
105         MaybeError InitializeAsInternalTexture(VkImageUsageFlags extraUsages);
106         MaybeError InitializeFromExternal(const ExternalImageDescriptorVk* descriptor,
107                                           external_memory::Service* externalMemoryService);
108         void InitializeForSwapChain(VkImage nativeImage);
109 
110         void DestroyImpl() override;
111         MaybeError ClearTexture(CommandRecordingContext* recordingContext,
112                                 const SubresourceRange& range,
113                                 TextureBase::ClearValue);
114 
115         // Implementation details of the barrier computations for the texture.
116         void TransitionUsageAndGetResourceBarrier(wgpu::TextureUsage usage,
117                                                   const SubresourceRange& range,
118                                                   std::vector<VkImageMemoryBarrier>* imageBarriers,
119                                                   VkPipelineStageFlags* srcStages,
120                                                   VkPipelineStageFlags* dstStages);
121         void TransitionUsageForPassImpl(
122             CommandRecordingContext* recordingContext,
123             const SubresourceStorage<wgpu::TextureUsage>& subresourceUsages,
124             std::vector<VkImageMemoryBarrier>* imageBarriers,
125             VkPipelineStageFlags* srcStages,
126             VkPipelineStageFlags* dstStages);
127         void TransitionUsageAndGetResourceBarrierImpl(
128             wgpu::TextureUsage usage,
129             const SubresourceRange& range,
130             std::vector<VkImageMemoryBarrier>* imageBarriers,
131             VkPipelineStageFlags* srcStages,
132             VkPipelineStageFlags* dstStages);
133         void TweakTransitionForExternalUsage(CommandRecordingContext* recordingContext,
134                                              std::vector<VkImageMemoryBarrier>* barriers,
135                                              size_t transitionBarrierStart);
136         bool CanReuseWithoutBarrier(wgpu::TextureUsage lastUsage, wgpu::TextureUsage usage);
137 
138         // In base Vulkan, Depth and stencil can only be transitioned together. This function
139         // indicates whether we should combine depth and stencil barriers to accommodate this
140         // limitation.
141         bool ShouldCombineDepthStencilBarriers() const;
142         // Compute the Aspects of the SubresourceStoage for this texture depending on whether we're
143         // doing the workaround for combined depth and stencil barriers.
144         Aspect ComputeAspectsForSubresourceStorage() const;
145 
146         VkImage mHandle = VK_NULL_HANDLE;
147         ResourceMemoryAllocation mMemoryAllocation;
148         VkDeviceMemory mExternalAllocation = VK_NULL_HANDLE;
149 
150         enum class ExternalState {
151             InternalOnly,
152             PendingAcquire,
153             Acquired,
154             Released
155         };
156         ExternalState mExternalState = ExternalState::InternalOnly;
157         ExternalState mLastExternalState = ExternalState::InternalOnly;
158 
159         VkImageLayout mPendingAcquireOldLayout;
160         VkImageLayout mPendingAcquireNewLayout;
161 
162         VkSemaphore mSignalSemaphore = VK_NULL_HANDLE;
163         std::vector<VkSemaphore> mWaitRequirements;
164 
165         // Note that in early Vulkan versions it is not possible to transition depth and stencil
166         // separately so textures with Depth|Stencil aspects will have a single Depth aspect in the
167         // storage.
168         SubresourceStorage<wgpu::TextureUsage> mSubresourceLastUsages;
169     };
170 
171     class TextureView final : public TextureViewBase {
172       public:
173         static ResultOrError<Ref<TextureView>> Create(TextureBase* texture,
174                                                       const TextureViewDescriptor* descriptor);
175         VkImageView GetHandle() const;
176 
177       private:
178         ~TextureView() override;
179         void DestroyImpl() override;
180         using TextureViewBase::TextureViewBase;
181         MaybeError Initialize(const TextureViewDescriptor* descriptor);
182 
183         // Dawn API
184         void SetLabelImpl() override;
185 
186         VkImageView mHandle = VK_NULL_HANDLE;
187     };
188 
189 }}  // namespace dawn_native::vulkan
190 
191 #endif  // DAWNNATIVE_VULKAN_TEXTUREVK_H_
192