diff --git a/src/dawn_native/BUILD.gn b/src/dawn_native/BUILD.gn index 5e1999f17f..4d0bd768ed 100644 --- a/src/dawn_native/BUILD.gn +++ b/src/dawn_native/BUILD.gn @@ -261,6 +261,8 @@ source_set("dawn_native_sources") { "SpirvUtils.h", "StagingBuffer.cpp", "StagingBuffer.h", + "Subresource.cpp", + "Subresource.h", "Surface.cpp", "Surface.h", "SwapChain.cpp", diff --git a/src/dawn_native/CMakeLists.txt b/src/dawn_native/CMakeLists.txt index 4321a447f6..e9b9580f3f 100644 --- a/src/dawn_native/CMakeLists.txt +++ b/src/dawn_native/CMakeLists.txt @@ -148,6 +148,8 @@ target_sources(dawn_native PRIVATE "SpirvUtils.h" "StagingBuffer.cpp" "StagingBuffer.h" + "Subresource.cpp" + "Subresource.h" "Surface.cpp" "Surface.h" "SwapChain.cpp" diff --git a/src/dawn_native/Subresource.cpp b/src/dawn_native/Subresource.cpp new file mode 100644 index 0000000000..f3581e9b41 --- /dev/null +++ b/src/dawn_native/Subresource.cpp @@ -0,0 +1,78 @@ +// Copyright 2020 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "dawn_native/Subresource.h" + +#include "common/Assert.h" +#include "dawn_native/Format.h" + +namespace dawn_native { + + Aspect ConvertSingleAspect(const Format& format, wgpu::TextureAspect aspect) { + Aspect aspectMask = ConvertAspect(format, aspect); + ASSERT(HasOneBit(aspectMask)); + return aspectMask; + } + + Aspect ConvertAspect(const Format& format, wgpu::TextureAspect aspect) { + Aspect aspectMask = TryConvertAspect(format, aspect); + ASSERT(aspectMask != Aspect::None); + return aspectMask; + } + + Aspect TryConvertAspect(const Format& format, wgpu::TextureAspect aspect) { + switch (aspect) { + case wgpu::TextureAspect::All: + return format.aspects; + case wgpu::TextureAspect::DepthOnly: + return format.aspects & Aspect::Depth; + case wgpu::TextureAspect::StencilOnly: + return format.aspects & Aspect::Stencil; + } + } + + uint8_t GetAspectIndex(Aspect aspect) { + ASSERT(HasOneBit(aspect)); + switch (aspect) { + case Aspect::Color: + return 0; + case Aspect::Depth: + return 0; + case Aspect::Stencil: + return 1; + default: + UNREACHABLE(); + } + } + + uint8_t GetAspectCount(Aspect aspects) { + // TODO(cwallez@chromium.org): This should use popcount once Dawn has such a function. + // Note that we can't do a switch because compilers complain that Depth | Stencil is not + // a valid enum value. + if (aspects == Aspect::Color || aspects == Aspect::Depth) { + return 1; + } else { + ASSERT(aspects == (Aspect::Depth | Aspect::Stencil)); + return 2; + } + } + + // static + SubresourceRange SubresourceRange::SingleMipAndLayer(uint32_t baseMipLevel, + uint32_t baseArrayLayer, + Aspect aspects) { + return {baseMipLevel, 1, baseArrayLayer, 1, aspects}; + } + +} // namespace dawn_native diff --git a/src/dawn_native/Subresource.h b/src/dawn_native/Subresource.h new file mode 100644 index 0000000000..b2f7d40b8e --- /dev/null +++ b/src/dawn_native/Subresource.h @@ -0,0 +1,78 @@ +// Copyright 2020 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef DAWNNATIVE_SUBRESOURCE_H_ +#define DAWNNATIVE_SUBRESOURCE_H_ + +#include "dawn_native/EnumClassBitmasks.h" +#include "dawn_native/dawn_platform.h" + +namespace dawn_native { + + // Note: Subresource indices are computed by iterating the aspects in increasing order. + // D3D12 uses these directly, so the order much match D3D12's indices. + // - Depth/Stencil textures have Depth as Plane 0, and Stencil as Plane 1. + enum class Aspect : uint8_t { + None = 0x0, + Color = 0x1, + Depth = 0x2, + Stencil = 0x4, + }; + + template <> + struct EnumBitmaskSize { + static constexpr unsigned value = 3; + }; + + // Convert the TextureAspect to an Aspect mask for the format. ASSERTs if the aspect + // does not exist in the format. + // Also ASSERTs if "All" is selected and results in more than one aspect. + Aspect ConvertSingleAspect(const Format& format, wgpu::TextureAspect aspect); + + // Convert the TextureAspect to an Aspect mask for the format. ASSERTs if the aspect + // does not exist in the format. + Aspect ConvertAspect(const Format& format, wgpu::TextureAspect aspect); + + // Try to convert the TextureAspect to an Aspect mask for the format. May return + // Aspect::None. + Aspect TryConvertAspect(const Format& format, wgpu::TextureAspect aspect); + + struct SubresourceRange { + uint32_t baseMipLevel; + uint32_t levelCount; + uint32_t baseArrayLayer; + uint32_t layerCount; + Aspect aspects; + + static SubresourceRange SingleMipAndLayer(uint32_t baseMipLevel, + uint32_t baseArrayLayer, + Aspect aspects); + }; + + // Helper function to use aspects as linear indices in arrays. + uint8_t GetAspectIndex(Aspect aspect); + uint8_t GetAspectCount(Aspect aspects); + +} // namespace dawn_native + +namespace wgpu { + + template <> + struct IsDawnBitmask { + static constexpr bool enable = true; + }; + +} // namespace wgpu + +#endif // DAWNNATIVE_SUBRESOURCE_H_ diff --git a/src/dawn_native/Texture.cpp b/src/dawn_native/Texture.cpp index fc751dcc3f..7e62d73322 100644 --- a/src/dawn_native/Texture.cpp +++ b/src/dawn_native/Texture.cpp @@ -211,11 +211,6 @@ namespace dawn_native { return {}; } - uint8_t GetPlaneIndex(Aspect aspect) { - ASSERT(HasOneBit(aspect)); - return static_cast(Log2(static_cast(aspect))); - } - } // anonymous namespace MaybeError ValidateTextureDescriptor(const DeviceBase* device, @@ -351,36 +346,6 @@ namespace dawn_native { } } - Aspect ConvertSingleAspect(const Format& format, wgpu::TextureAspect aspect) { - Aspect aspectMask = ConvertAspect(format, aspect); - ASSERT(HasOneBit(aspectMask)); - return aspectMask; - } - - Aspect ConvertAspect(const Format& format, wgpu::TextureAspect aspect) { - Aspect aspectMask = TryConvertAspect(format, aspect); - ASSERT(aspectMask != Aspect::None); - return aspectMask; - } - - Aspect TryConvertAspect(const Format& format, wgpu::TextureAspect aspect) { - switch (aspect) { - case wgpu::TextureAspect::All: - return format.aspects; - case wgpu::TextureAspect::DepthOnly: - return format.aspects & Aspect::Depth; - case wgpu::TextureAspect::StencilOnly: - return format.aspects & Aspect::Stencil; - } - } - - // static - SubresourceRange SubresourceRange::SingleMipAndLayer(uint32_t baseMipLevel, - uint32_t baseArrayLayer, - Aspect aspects) { - return {baseMipLevel, 1, baseArrayLayer, 1, aspects}; - } - // TextureBase TextureBase::TextureBase(DeviceBase* device, @@ -394,13 +359,7 @@ namespace dawn_native { mSampleCount(descriptor->sampleCount), mUsage(descriptor->usage), mState(state) { - uint8_t planeIndex = 0; - for (Aspect aspect : IterateEnumMask(mFormat.aspects)) { - mPlaneIndices[GetPlaneIndex(aspect)] = planeIndex++; - } - - uint32_t subresourceCount = - mMipLevelCount * mSize.depth * static_cast(planeIndex); + uint32_t subresourceCount = mMipLevelCount * mSize.depth * GetAspectCount(mFormat.aspects); mIsSubresourceContentInitializedAtIndex = std::vector(subresourceCount, false); // Add readonly storage usage if the texture has a storage usage. The validation rules in @@ -492,8 +451,7 @@ namespace dawn_native { std::numeric_limits::max() / kMaxTexture2DArrayLayers, "texture size overflows uint32_t"); return mipLevel + - GetNumMipLevels() * - (arraySlice + GetArrayLayers() * mPlaneIndices[GetPlaneIndex(aspect)]); + GetNumMipLevels() * (arraySlice + GetArrayLayers() * GetAspectIndex(aspect)); } bool TextureBase::IsSubresourceContentInitialized(const SubresourceRange& range) const { diff --git a/src/dawn_native/Texture.h b/src/dawn_native/Texture.h index 29a34c17ac..18c3e7867e 100644 --- a/src/dawn_native/Texture.h +++ b/src/dawn_native/Texture.h @@ -17,43 +17,15 @@ #include "common/ityp_array.h" #include "common/ityp_bitset.h" -#include "dawn_native/EnumClassBitmasks.h" #include "dawn_native/Error.h" #include "dawn_native/Forward.h" #include "dawn_native/ObjectBase.h" +#include "dawn_native/Subresource.h" #include "dawn_native/dawn_platform.h" #include -namespace dawn_native { - - // Note: Subresource indices are computed by iterating the aspects in increasing order. - // D3D12 uses these directly, so the order much match D3D12's indices. - // - Depth/Stencil textures have Depth as Plane 0, and Stencil as Plane 1. - enum class Aspect : uint8_t { - None = 0x0, - Color = 0x1, - Depth = 0x2, - Stencil = 0x4, - }; - - template <> - struct EnumBitmaskSize { - static constexpr unsigned value = 3; - }; - -} // namespace dawn_native - -namespace wgpu { - - template <> - struct IsDawnBitmask { - static constexpr bool enable = true; - }; - -} // namespace wgpu - namespace dawn_native { MaybeError ValidateTextureDescriptor(const DeviceBase* device, @@ -73,31 +45,6 @@ namespace dawn_native { wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Storage | wgpu::TextureUsage::RenderAttachment; - // Convert the TextureAspect to an Aspect mask for the format. ASSERTs if the aspect - // does not exist in the format. - // Also ASSERTs if "All" is selected and results in more than one aspect. - Aspect ConvertSingleAspect(const Format& format, wgpu::TextureAspect aspect); - - // Convert the TextureAspect to an Aspect mask for the format. ASSERTs if the aspect - // does not exist in the format. - Aspect ConvertAspect(const Format& format, wgpu::TextureAspect aspect); - - // Try to convert the TextureAspect to an Aspect mask for the format. May return - // Aspect::None. - Aspect TryConvertAspect(const Format& format, wgpu::TextureAspect aspect); - - struct SubresourceRange { - uint32_t baseMipLevel; - uint32_t levelCount; - uint32_t baseArrayLayer; - uint32_t layerCount; - Aspect aspects; - - static SubresourceRange SingleMipAndLayer(uint32_t baseMipLevel, - uint32_t baseArrayLayer, - Aspect aspects); - }; - class TextureBase : public ObjectBase { public: enum class TextureState { OwnedInternal, OwnedExternal, Destroyed }; @@ -161,7 +108,6 @@ namespace dawn_native { // TODO(natlee@microsoft.com): Use a more optimized data structure to save space std::vector mIsSubresourceContentInitializedAtIndex; - std::array::value> mPlaneIndices; }; class TextureViewBase : public ObjectBase {