1 // Copyright 2017 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_TEXTURE_H_
16 #define DAWNNATIVE_TEXTURE_H_
17 
18 #include "common/ityp_array.h"
19 #include "common/ityp_bitset.h"
20 #include "dawn_native/EnumClassBitmasks.h"
21 #include "dawn_native/Error.h"
22 #include "dawn_native/Forward.h"
23 #include "dawn_native/ObjectBase.h"
24 
25 #include "dawn_native/dawn_platform.h"
26 
27 #include <vector>
28 
29 namespace dawn_native {
30 
31     // Note: Subresource indices are computed by iterating the aspects in increasing order.
32     // D3D12 uses these directly, so the order much match D3D12's indices.
33     //  - Depth/Stencil textures have Depth as Plane 0, and Stencil as Plane 1.
34     enum class Aspect : uint8_t {
35         None = 0x0,
36         Color = 0x1,
37         Depth = 0x2,
38         Stencil = 0x4,
39     };
40 
41     template <>
42     struct EnumBitmaskSize<Aspect> {
43         static constexpr unsigned value = 3;
44     };
45 
46 }  // namespace dawn_native
47 
48 namespace wgpu {
49 
50     template <>
51     struct IsDawnBitmask<dawn_native::Aspect> {
52         static constexpr bool enable = true;
53     };
54 
55 }  // namespace wgpu
56 
57 namespace dawn_native {
58 
59     MaybeError ValidateTextureDescriptor(const DeviceBase* device,
60                                          const TextureDescriptor* descriptor);
61     MaybeError ValidateTextureViewDescriptor(const TextureBase* texture,
62                                              const TextureViewDescriptor* descriptor);
63     TextureViewDescriptor GetTextureViewDescriptorWithDefaults(
64         const TextureBase* texture,
65         const TextureViewDescriptor* descriptor);
66 
67     bool IsValidSampleCount(uint32_t sampleCount);
68 
69     static constexpr wgpu::TextureUsage kReadOnlyTextureUsages =
70         wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::Sampled | kReadonlyStorageTexture;
71 
72     static constexpr wgpu::TextureUsage kWritableTextureUsages =
73         wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Storage |
74         wgpu::TextureUsage::RenderAttachment;
75 
76     // Convert the TextureAspect to an Aspect mask for the format. ASSERTs if the aspect
77     // does not exist in the format.
78     // Also ASSERTs if "All" is selected and results in more than one aspect.
79     Aspect ConvertSingleAspect(const Format& format, wgpu::TextureAspect aspect);
80 
81     // Convert the TextureAspect to an Aspect mask for the format. ASSERTs if the aspect
82     // does not exist in the format.
83     Aspect ConvertAspect(const Format& format, wgpu::TextureAspect aspect);
84 
85     // Try to convert the TextureAspect to an Aspect mask for the format. May return
86     // Aspect::None.
87     Aspect TryConvertAspect(const Format& format, wgpu::TextureAspect aspect);
88 
89     struct SubresourceRange {
90         uint32_t baseMipLevel;
91         uint32_t levelCount;
92         uint32_t baseArrayLayer;
93         uint32_t layerCount;
94         Aspect aspects;
95 
96         static SubresourceRange SingleMipAndLayer(uint32_t baseMipLevel,
97                                                   uint32_t baseArrayLayer,
98                                                   Aspect aspects);
99     };
100 
101     class TextureBase : public ObjectBase {
102       public:
103         enum class TextureState { OwnedInternal, OwnedExternal, Destroyed };
104         enum class ClearValue { Zero, NonZero };
105         TextureBase(DeviceBase* device, const TextureDescriptor* descriptor, TextureState state);
106 
107         static TextureBase* MakeError(DeviceBase* device);
108 
109         wgpu::TextureDimension GetDimension() const;
110         const Format& GetFormat() const;
111         const Extent3D& GetSize() const;
112         uint32_t GetWidth() const;
113         uint32_t GetHeight() const;
114         uint32_t GetDepth() const;
115         uint32_t GetArrayLayers() const;
116         uint32_t GetNumMipLevels() const;
117         SubresourceRange GetAllSubresources() const;
118         uint32_t GetSampleCount() const;
119         uint32_t GetSubresourceCount() const;
120         wgpu::TextureUsage GetUsage() const;
121         TextureState GetTextureState() const;
122         uint32_t GetSubresourceIndex(uint32_t mipLevel, uint32_t arraySlice, Aspect aspect) const;
123         bool IsSubresourceContentInitialized(const SubresourceRange& range) const;
124         void SetIsSubresourceContentInitialized(bool isInitialized, const SubresourceRange& range);
125 
126         MaybeError ValidateCanUseInSubmitNow() const;
127 
128         bool IsMultisampledTexture() const;
129 
130         // For a texture with non-block-compressed texture format, its physical size is always equal
131         // to its virtual size. For a texture with block compressed texture format, the physical
132         // size is the one with paddings if necessary, which is always a multiple of the block size
133         // and used in texture copying. The virtual size is the one without paddings, which is not
134         // required to be a multiple of the block size and used in texture sampling.
135         Extent3D GetMipLevelPhysicalSize(uint32_t level) const;
136         Extent3D GetMipLevelVirtualSize(uint32_t level) const;
137         Extent3D ClampToMipLevelVirtualSize(uint32_t level,
138                                             const Origin3D& origin,
139                                             const Extent3D& extent) const;
140 
141         // Dawn API
142         TextureViewBase* CreateView(const TextureViewDescriptor* descriptor);
143         void Destroy();
144 
145       protected:
146         void DestroyInternal();
147 
148       private:
149         TextureBase(DeviceBase* device, ObjectBase::ErrorTag tag);
150         virtual void DestroyImpl();
151 
152         MaybeError ValidateDestroy() const;
153         wgpu::TextureDimension mDimension;
154         // TODO(cwallez@chromium.org): This should be deduplicated in the Device
155         const Format& mFormat;
156         Extent3D mSize;
157         uint32_t mMipLevelCount;
158         uint32_t mSampleCount;
159         wgpu::TextureUsage mUsage = wgpu::TextureUsage::None;
160         TextureState mState;
161 
162         // TODO(natlee@microsoft.com): Use a more optimized data structure to save space
163         std::vector<bool> mIsSubresourceContentInitializedAtIndex;
164         std::array<uint8_t, EnumBitmaskSize<Aspect>::value> mPlaneIndices;
165     };
166 
167     class TextureViewBase : public ObjectBase {
168       public:
169         TextureViewBase(TextureBase* texture, const TextureViewDescriptor* descriptor);
170 
171         static TextureViewBase* MakeError(DeviceBase* device);
172 
173         const TextureBase* GetTexture() const;
174         TextureBase* GetTexture();
175 
176         Aspect GetAspects() const;
177         const Format& GetFormat() const;
178         wgpu::TextureViewDimension GetDimension() const;
179         uint32_t GetBaseMipLevel() const;
180         uint32_t GetLevelCount() const;
181         uint32_t GetBaseArrayLayer() const;
182         uint32_t GetLayerCount() const;
183         const SubresourceRange& GetSubresourceRange() const;
184 
185       private:
186         TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag);
187 
188         Ref<TextureBase> mTexture;
189 
190         // TODO(cwallez@chromium.org): This should be deduplicated in the Device
191         const Format& mFormat;
192         wgpu::TextureViewDimension mDimension;
193         SubresourceRange mRange;
194     };
195 
196 }  // namespace dawn_native
197 
198 #endif  // DAWNNATIVE_TEXTURE_H_
199