| // Copyright 2020 The Dawn & Tint Authors |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are met: |
| // |
| // 1. Redistributions of source code must retain the above copyright notice, this |
| // list of conditions and the following disclaimer. |
| // |
| // 2. Redistributions in binary form must reproduce the above copyright notice, |
| // this list of conditions and the following disclaimer in the documentation |
| // and/or other materials provided with the distribution. |
| // |
| // 3. Neither the name of the copyright holder nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
| // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| #include "dawn/native/Subresource.h" |
| |
| #include "absl/numeric/bits.h" |
| #include "dawn/common/Assert.h" |
| #include "dawn/native/Format.h" |
| |
| namespace dawn::native { |
| |
| Aspect ConvertSingleAspect(const Format& format, wgpu::TextureAspect aspect) { |
| Aspect aspectMask = ConvertAspect(format, aspect); |
| DAWN_ASSERT(HasOneBit(aspectMask)); |
| return aspectMask; |
| } |
| |
| Aspect ConvertAspect(const Format& format, wgpu::TextureAspect aspect) { |
| Aspect aspectMask = SelectFormatAspects(format, aspect); |
| DAWN_ASSERT(aspectMask != Aspect::None); |
| return aspectMask; |
| } |
| |
| Aspect ConvertViewAspect(const Format& format, wgpu::TextureAspect aspect) { |
| // Color view |format| must be treated as the same plane |aspect|. |
| if (format.aspects == Aspect::Color) { |
| switch (aspect) { |
| case wgpu::TextureAspect::Plane0Only: |
| return Aspect::Plane0; |
| case wgpu::TextureAspect::Plane1Only: |
| return Aspect::Plane1; |
| case wgpu::TextureAspect::Plane2Only: |
| return Aspect::Plane2; |
| default: |
| break; |
| } |
| } |
| return ConvertAspect(format, aspect); |
| } |
| |
| Aspect GetPlaneAspect(const Format& format, uint32_t planeIndex) { |
| wgpu::TextureAspect textureAspect; |
| switch (planeIndex) { |
| case 0: |
| textureAspect = wgpu::TextureAspect::Plane0Only; |
| break; |
| case 1: |
| textureAspect = wgpu::TextureAspect::Plane1Only; |
| break; |
| case 2: |
| textureAspect = wgpu::TextureAspect::Plane2Only; |
| break; |
| default: |
| DAWN_UNREACHABLE(); |
| } |
| |
| return ConvertAspect(format, textureAspect); |
| } |
| |
| Aspect SelectFormatAspects(const Format& format, wgpu::TextureAspect aspect) { |
| // TODO(crbug.com/dawn/2476): Return Aspect::Color for TextureFormat::External if aspect is |
| // present else None. |
| 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; |
| case wgpu::TextureAspect::Plane0Only: |
| return format.aspects & Aspect::Plane0; |
| case wgpu::TextureAspect::Plane1Only: |
| return format.aspects & Aspect::Plane1; |
| case wgpu::TextureAspect::Plane2Only: |
| return format.aspects & Aspect::Plane2; |
| case wgpu::TextureAspect::Undefined: |
| break; |
| } |
| DAWN_UNREACHABLE(); |
| } |
| |
| uint8_t GetAspectIndex(Aspect aspect) { |
| DAWN_ASSERT(HasOneBit(aspect)); |
| switch (aspect) { |
| case Aspect::Color: |
| case Aspect::Depth: |
| case Aspect::Plane0: |
| case Aspect::CombinedDepthStencil: |
| return 0; |
| case Aspect::Plane1: |
| case Aspect::Stencil: |
| return 1; |
| case Aspect::Plane2: |
| return 2; |
| default: |
| DAWN_UNREACHABLE(); |
| } |
| } |
| |
| uint8_t GetAspectCount(Aspect aspects) { |
| if (aspects == Aspect::Stencil) { |
| // Fake a the existence of a depth aspect so that the stencil data stays at index 1. |
| DAWN_ASSERT(GetAspectIndex(Aspect::Stencil) == 1); |
| return 2; |
| } |
| return absl::popcount(static_cast<uint8_t>(aspects)); |
| } |
| |
| SubresourceRange::SubresourceRange(Aspect aspects, |
| FirstAndCountRange<uint32_t> arrayLayerParam, |
| FirstAndCountRange<uint32_t> mipLevelParams) |
| : aspects(aspects), |
| baseArrayLayer(arrayLayerParam.first), |
| layerCount(arrayLayerParam.count), |
| baseMipLevel(mipLevelParams.first), |
| levelCount(mipLevelParams.count) {} |
| |
| SubresourceRange::SubresourceRange() |
| : aspects(Aspect::None), baseArrayLayer(0), layerCount(0), baseMipLevel(0), levelCount(0) {} |
| |
| // static |
| SubresourceRange SubresourceRange::SingleMipAndLayer(uint32_t baseMipLevel, |
| uint32_t baseArrayLayer, |
| Aspect aspects) { |
| return {aspects, {baseArrayLayer, 1}, {baseMipLevel, 1}}; |
| } |
| |
| // static |
| SubresourceRange SubresourceRange::MakeSingle(Aspect aspect, |
| uint32_t baseArrayLayer, |
| uint32_t baseMipLevel) { |
| DAWN_ASSERT(HasOneBit(aspect)); |
| return {aspect, {baseArrayLayer, 1}, {baseMipLevel, 1}}; |
| } |
| |
| // static |
| SubresourceRange SubresourceRange::MakeFull(Aspect aspects, |
| uint32_t layerCount, |
| uint32_t levelCount) { |
| return {aspects, {0, layerCount}, {0, levelCount}}; |
| } |
| |
| } // namespace dawn::native |