Move Subresource-related datatypes to their own file.

Aspect and SubresourceRange will be used by the SubresourceStorage
container that will itself be used by TextureBase. Avoid cyclic header
dependencies by moving SubresourceRange and Aspect to their own header.

Also refactors the handling of Aspect to aspect index in preparation for
using it in SubresourceStorage (each Aspect will have a fixed index).

Bug: dawn:441

Change-Id: I66c60f899d236a233ef30a287227610f8b469f88
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/34463
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2020-12-03 17:55:03 +00:00 committed by Commit Bot service account
parent c34bb0c3c4
commit fe129405cf
6 changed files with 163 additions and 99 deletions

View File

@ -261,6 +261,8 @@ source_set("dawn_native_sources") {
"SpirvUtils.h", "SpirvUtils.h",
"StagingBuffer.cpp", "StagingBuffer.cpp",
"StagingBuffer.h", "StagingBuffer.h",
"Subresource.cpp",
"Subresource.h",
"Surface.cpp", "Surface.cpp",
"Surface.h", "Surface.h",
"SwapChain.cpp", "SwapChain.cpp",

View File

@ -148,6 +148,8 @@ target_sources(dawn_native PRIVATE
"SpirvUtils.h" "SpirvUtils.h"
"StagingBuffer.cpp" "StagingBuffer.cpp"
"StagingBuffer.h" "StagingBuffer.h"
"Subresource.cpp"
"Subresource.h"
"Surface.cpp" "Surface.cpp"
"Surface.h" "Surface.h"
"SwapChain.cpp" "SwapChain.cpp"

View File

@ -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

View File

@ -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<Aspect> {
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<dawn_native::Aspect> {
static constexpr bool enable = true;
};
} // namespace wgpu
#endif // DAWNNATIVE_SUBRESOURCE_H_

View File

@ -211,11 +211,6 @@ namespace dawn_native {
return {}; return {};
} }
uint8_t GetPlaneIndex(Aspect aspect) {
ASSERT(HasOneBit(aspect));
return static_cast<uint8_t>(Log2(static_cast<uint32_t>(aspect)));
}
} // anonymous namespace } // anonymous namespace
MaybeError ValidateTextureDescriptor(const DeviceBase* device, 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::TextureBase(DeviceBase* device, TextureBase::TextureBase(DeviceBase* device,
@ -394,13 +359,7 @@ namespace dawn_native {
mSampleCount(descriptor->sampleCount), mSampleCount(descriptor->sampleCount),
mUsage(descriptor->usage), mUsage(descriptor->usage),
mState(state) { mState(state) {
uint8_t planeIndex = 0; uint32_t subresourceCount = mMipLevelCount * mSize.depth * GetAspectCount(mFormat.aspects);
for (Aspect aspect : IterateEnumMask(mFormat.aspects)) {
mPlaneIndices[GetPlaneIndex(aspect)] = planeIndex++;
}
uint32_t subresourceCount =
mMipLevelCount * mSize.depth * static_cast<uint32_t>(planeIndex);
mIsSubresourceContentInitializedAtIndex = std::vector<bool>(subresourceCount, false); mIsSubresourceContentInitializedAtIndex = std::vector<bool>(subresourceCount, false);
// Add readonly storage usage if the texture has a storage usage. The validation rules in // 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<uint32_t>::max() / kMaxTexture2DArrayLayers, std::numeric_limits<uint32_t>::max() / kMaxTexture2DArrayLayers,
"texture size overflows uint32_t"); "texture size overflows uint32_t");
return mipLevel + return mipLevel +
GetNumMipLevels() * GetNumMipLevels() * (arraySlice + GetArrayLayers() * GetAspectIndex(aspect));
(arraySlice + GetArrayLayers() * mPlaneIndices[GetPlaneIndex(aspect)]);
} }
bool TextureBase::IsSubresourceContentInitialized(const SubresourceRange& range) const { bool TextureBase::IsSubresourceContentInitialized(const SubresourceRange& range) const {

View File

@ -17,43 +17,15 @@
#include "common/ityp_array.h" #include "common/ityp_array.h"
#include "common/ityp_bitset.h" #include "common/ityp_bitset.h"
#include "dawn_native/EnumClassBitmasks.h"
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
#include "dawn_native/Forward.h" #include "dawn_native/Forward.h"
#include "dawn_native/ObjectBase.h" #include "dawn_native/ObjectBase.h"
#include "dawn_native/Subresource.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
#include <vector> #include <vector>
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<Aspect> {
static constexpr unsigned value = 3;
};
} // namespace dawn_native
namespace wgpu {
template <>
struct IsDawnBitmask<dawn_native::Aspect> {
static constexpr bool enable = true;
};
} // namespace wgpu
namespace dawn_native { namespace dawn_native {
MaybeError ValidateTextureDescriptor(const DeviceBase* device, MaybeError ValidateTextureDescriptor(const DeviceBase* device,
@ -73,31 +45,6 @@ namespace dawn_native {
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Storage | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Storage |
wgpu::TextureUsage::RenderAttachment; 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 { class TextureBase : public ObjectBase {
public: public:
enum class TextureState { OwnedInternal, OwnedExternal, Destroyed }; 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 // TODO(natlee@microsoft.com): Use a more optimized data structure to save space
std::vector<bool> mIsSubresourceContentInitializedAtIndex; std::vector<bool> mIsSubresourceContentInitializedAtIndex;
std::array<uint8_t, EnumBitmaskSize<Aspect>::value> mPlaneIndices;
}; };
class TextureViewBase : public ObjectBase { class TextureViewBase : public ObjectBase {