Corentin Wallez | 4a9ef4e | 2018-07-18 11:40:26 +0200 | [diff] [blame] | 1 | // Copyright 2017 The Dawn Authors |
Corentin Wallez | 0ba5550 | 2017-06-14 15:46:59 -0400 | [diff] [blame] | 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 | |
Corentin Wallez | d37523f | 2018-07-24 13:53:51 +0200 | [diff] [blame] | 15 | #include "dawn_native/metal/TextureMTL.h" |
Corentin Wallez | 0ba5550 | 2017-06-14 15:46:59 -0400 | [diff] [blame] | 16 | |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 17 | #include "common/Constants.h" |
| 18 | #include "common/Math.h" |
Corentin Wallez | b495e48 | 2019-09-18 04:32:52 +0000 | [diff] [blame] | 19 | #include "common/Platform.h" |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 20 | #include "dawn_native/DynamicUploader.h" |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 21 | #include "dawn_native/EnumMaskIterator.h" |
Corentin Wallez | d37523f | 2018-07-24 13:53:51 +0200 | [diff] [blame] | 22 | #include "dawn_native/metal/DeviceMTL.h" |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 23 | #include "dawn_native/metal/StagingBufferMTL.h" |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 24 | #include "dawn_native/metal/UtilsMetal.h" |
Corentin Wallez | 0ba5550 | 2017-06-14 15:46:59 -0400 | [diff] [blame] | 25 | |
Corentin Wallez | c85ef79 | 2020-04-29 21:07:21 +0000 | [diff] [blame] | 26 | #include <CoreVideo/CVPixelBuffer.h> |
| 27 | |
Corentin Wallez | 49a65d0 | 2018-07-24 16:45:45 +0200 | [diff] [blame] | 28 | namespace dawn_native { namespace metal { |
Corentin Wallez | 8308b1c | 2017-07-03 23:02:49 -0400 | [diff] [blame] | 29 | |
Austin Eng | 476e5cb | 2017-08-03 12:17:14 -0400 | [diff] [blame] | 30 | namespace { |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 31 | bool UsageNeedsTextureView(wgpu::TextureUsage usage) { |
| 32 | constexpr wgpu::TextureUsage kUsageNeedsTextureView = |
Brandon Jones | 27e17a6 | 2021-08-10 04:07:37 +0000 | [diff] [blame] | 33 | wgpu::TextureUsage::StorageBinding | wgpu::TextureUsage::TextureBinding; |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 34 | return usage & kUsageNeedsTextureView; |
| 35 | } |
| 36 | |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 37 | MTLTextureUsage MetalTextureUsage(const Format& format, |
| 38 | wgpu::TextureUsage usage, |
| 39 | uint32_t sampleCount) { |
Corentin Wallez | f58d84d | 2017-11-24 14:12:44 -0500 | [diff] [blame] | 40 | MTLTextureUsage result = MTLTextureUsageUnknown; // This is 0 |
Corentin Wallez | 8308b1c | 2017-07-03 23:02:49 -0400 | [diff] [blame] | 41 | |
Brandon Jones | 27e17a6 | 2021-08-10 04:07:37 +0000 | [diff] [blame] | 42 | if (usage & (wgpu::TextureUsage::StorageBinding)) { |
Corentin Wallez | 8308b1c | 2017-07-03 23:02:49 -0400 | [diff] [blame] | 43 | result |= MTLTextureUsageShaderWrite | MTLTextureUsageShaderRead; |
| 44 | } |
| 45 | |
Brandon Jones | 27e17a6 | 2021-08-10 04:07:37 +0000 | [diff] [blame] | 46 | if (usage & (wgpu::TextureUsage::TextureBinding)) { |
Corentin Wallez | 8308b1c | 2017-07-03 23:02:49 -0400 | [diff] [blame] | 47 | result |= MTLTextureUsageShaderRead; |
Austin Eng | a0f1725 | 2020-11-04 15:27:11 +0000 | [diff] [blame] | 48 | |
| 49 | // For sampling stencil aspect of combined depth/stencil. See TextureView |
| 50 | // constructor. |
| 51 | if (@available(macOS 10.12, iOS 10.0, *)) { |
| 52 | if (IsSubset(Aspect::Depth | Aspect::Stencil, format.aspects)) { |
| 53 | result |= MTLTextureUsagePixelFormatView; |
| 54 | } |
| 55 | } |
Corentin Wallez | 8308b1c | 2017-07-03 23:02:49 -0400 | [diff] [blame] | 56 | } |
| 57 | |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 58 | // MTLTextureUsageRenderTarget is needed to clear multisample textures. |
| 59 | if (usage & (wgpu::TextureUsage::RenderAttachment) || sampleCount > 1) { |
Corentin Wallez | 8308b1c | 2017-07-03 23:02:49 -0400 | [diff] [blame] | 60 | result |= MTLTextureUsageRenderTarget; |
| 61 | } |
| 62 | |
| 63 | return result; |
| 64 | } |
| 65 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 66 | MTLTextureType MetalTextureViewType(wgpu::TextureViewDimension dimension, |
Jiawei Shao | 865cad8 | 2019-04-09 08:04:59 +0000 | [diff] [blame] | 67 | unsigned int sampleCount) { |
Jiawei Shao | e8d12b4 | 2018-10-26 06:29:38 +0000 | [diff] [blame] | 68 | switch (dimension) { |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 69 | case wgpu::TextureViewDimension::e2D: |
Jiawei Shao | 865cad8 | 2019-04-09 08:04:59 +0000 | [diff] [blame] | 70 | return (sampleCount > 1) ? MTLTextureType2DMultisample : MTLTextureType2D; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 71 | case wgpu::TextureViewDimension::e2DArray: |
Jiawei Shao | e8d12b4 | 2018-10-26 06:29:38 +0000 | [diff] [blame] | 72 | return MTLTextureType2DArray; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 73 | case wgpu::TextureViewDimension::Cube: |
Jiawei Shao | 5ab84ec | 2018-11-16 12:11:20 +0000 | [diff] [blame] | 74 | return MTLTextureTypeCube; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 75 | case wgpu::TextureViewDimension::CubeArray: |
Jiawei Shao | 5ab84ec | 2018-11-16 12:11:20 +0000 | [diff] [blame] | 76 | return MTLTextureTypeCubeArray; |
Yunchao He | 1b9bcfc | 2021-02-03 16:36:59 +0000 | [diff] [blame] | 77 | case wgpu::TextureViewDimension::e3D: |
| 78 | return MTLTextureType3D; |
Corentin Wallez | eec9edf | 2020-09-24 14:56:50 +0000 | [diff] [blame] | 79 | |
| 80 | case wgpu::TextureViewDimension::e1D: |
Corentin Wallez | eec9edf | 2020-09-24 14:56:50 +0000 | [diff] [blame] | 81 | case wgpu::TextureViewDimension::Undefined: |
Jiawei Shao | e8d12b4 | 2018-10-26 06:29:38 +0000 | [diff] [blame] | 82 | UNREACHABLE(); |
Jiawei Shao | e8d12b4 | 2018-10-26 06:29:38 +0000 | [diff] [blame] | 83 | } |
| 84 | } |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 85 | |
| 86 | bool RequiresCreatingNewTextureView(const TextureBase* texture, |
| 87 | const TextureViewDescriptor* textureViewDescriptor) { |
Corentin Wallez | a92f83b | 2019-06-21 10:16:15 +0000 | [diff] [blame] | 88 | if (texture->GetFormat().format != textureViewDescriptor->format) { |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 89 | return true; |
| 90 | } |
| 91 | |
Jiawei Shao | 2030166 | 2019-02-21 00:45:19 +0000 | [diff] [blame] | 92 | if (texture->GetArrayLayers() != textureViewDescriptor->arrayLayerCount) { |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 93 | return true; |
| 94 | } |
| 95 | |
Jiawei Shao | 2030166 | 2019-02-21 00:45:19 +0000 | [diff] [blame] | 96 | if (texture->GetNumMipLevels() != textureViewDescriptor->mipLevelCount) { |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 97 | return true; |
| 98 | } |
| 99 | |
Austin Eng | a0f1725 | 2020-11-04 15:27:11 +0000 | [diff] [blame] | 100 | if (IsSubset(Aspect::Depth | Aspect::Stencil, texture->GetFormat().aspects) && |
| 101 | textureViewDescriptor->aspect == wgpu::TextureAspect::StencilOnly) { |
| 102 | return true; |
| 103 | } |
| 104 | |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 105 | switch (textureViewDescriptor->dimension) { |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 106 | case wgpu::TextureViewDimension::Cube: |
| 107 | case wgpu::TextureViewDimension::CubeArray: |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 108 | return true; |
| 109 | default: |
| 110 | break; |
| 111 | } |
| 112 | |
| 113 | return false; |
| 114 | } |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 115 | |
Yan | cf0e4fc | 2022-01-06 09:01:58 +0000 | [diff] [blame^] | 116 | // Metal only allows format reinterpretation to happen on swizzle pattern or conversion |
| 117 | // between linear space and sRGB without setting MTLTextureUsagePixelFormatView flag. For |
| 118 | // example, creating bgra8Unorm texture view on rgba8Unorm texture or creating |
| 119 | // rgba8Unorm_srgb texture view on rgab8Unorm texture. |
| 120 | bool AllowFormatReinterpretationWithoutFlag(MTLPixelFormat origin, |
| 121 | MTLPixelFormat reinterpretation) { |
| 122 | switch (origin) { |
| 123 | case MTLPixelFormatRGBA8Unorm: |
| 124 | return reinterpretation == MTLPixelFormatBGRA8Unorm || |
| 125 | reinterpretation == MTLPixelFormatRGBA8Unorm_sRGB; |
| 126 | case MTLPixelFormatBGRA8Unorm: |
| 127 | return reinterpretation == MTLPixelFormatRGBA8Unorm || |
| 128 | reinterpretation == MTLPixelFormatBGRA8Unorm_sRGB; |
| 129 | case MTLPixelFormatRGBA8Unorm_sRGB: |
| 130 | return reinterpretation == MTLPixelFormatBGRA8Unorm_sRGB || |
| 131 | reinterpretation == MTLPixelFormatRGBA8Unorm; |
| 132 | case MTLPixelFormatBGRA8Unorm_sRGB: |
| 133 | return reinterpretation == MTLPixelFormatRGBA8Unorm_sRGB || |
| 134 | reinterpretation == MTLPixelFormatBGRA8Unorm; |
| 135 | #if defined(DAWN_PLATFORM_MACOS) |
| 136 | case MTLPixelFormatBC1_RGBA: |
| 137 | return reinterpretation == MTLPixelFormatBC1_RGBA_sRGB; |
| 138 | case MTLPixelFormatBC1_RGBA_sRGB: |
| 139 | return reinterpretation == MTLPixelFormatBC1_RGBA; |
| 140 | case MTLPixelFormatBC2_RGBA: |
| 141 | return reinterpretation == MTLPixelFormatBC2_RGBA_sRGB; |
| 142 | case MTLPixelFormatBC2_RGBA_sRGB: |
| 143 | return reinterpretation == MTLPixelFormatBC2_RGBA; |
| 144 | case MTLPixelFormatBC3_RGBA: |
| 145 | return reinterpretation == MTLPixelFormatBC3_RGBA_sRGB; |
| 146 | case MTLPixelFormatBC3_RGBA_sRGB: |
| 147 | return reinterpretation == MTLPixelFormatBC3_RGBA; |
| 148 | case MTLPixelFormatBC7_RGBAUnorm: |
| 149 | return reinterpretation == MTLPixelFormatBC7_RGBAUnorm_sRGB; |
| 150 | case MTLPixelFormatBC7_RGBAUnorm_sRGB: |
| 151 | return reinterpretation == MTLPixelFormatBC7_RGBAUnorm; |
| 152 | #endif |
| 153 | |
| 154 | default: |
| 155 | return false; |
| 156 | } |
| 157 | } |
| 158 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 159 | ResultOrError<wgpu::TextureFormat> GetFormatEquivalentToIOSurfaceFormat(uint32_t format) { |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 160 | switch (format) { |
Corentin Wallez | c85ef79 | 2020-04-29 21:07:21 +0000 | [diff] [blame] | 161 | case kCVPixelFormatType_32RGBA: |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 162 | return wgpu::TextureFormat::RGBA8Unorm; |
Corentin Wallez | c85ef79 | 2020-04-29 21:07:21 +0000 | [diff] [blame] | 163 | case kCVPixelFormatType_32BGRA: |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 164 | return wgpu::TextureFormat::BGRA8Unorm; |
Corentin Wallez | c85ef79 | 2020-04-29 21:07:21 +0000 | [diff] [blame] | 165 | case kCVPixelFormatType_TwoComponent8: |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 166 | return wgpu::TextureFormat::RG8Unorm; |
Corentin Wallez | c85ef79 | 2020-04-29 21:07:21 +0000 | [diff] [blame] | 167 | case kCVPixelFormatType_OneComponent8: |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 168 | return wgpu::TextureFormat::R8Unorm; |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 169 | default: |
Brandon Jones | eb0d900 | 2021-10-22 17:39:20 +0000 | [diff] [blame] | 170 | return DAWN_FORMAT_VALIDATION_ERROR("Unsupported IOSurface format (%x).", |
| 171 | format); |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 172 | } |
| 173 | } |
Corentin Wallez | b495e48 | 2019-09-18 04:32:52 +0000 | [diff] [blame] | 174 | |
| 175 | #if defined(DAWN_PLATFORM_MACOS) |
| 176 | MTLStorageMode kIOSurfaceStorageMode = MTLStorageModeManaged; |
| 177 | #elif defined(DAWN_PLATFORM_IOS) |
| 178 | MTLStorageMode kIOSurfaceStorageMode = MTLStorageModePrivate; |
| 179 | #else |
| 180 | # error "Unsupported Apple platform." |
| 181 | #endif |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 182 | } |
| 183 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 184 | MTLPixelFormat MetalPixelFormat(wgpu::TextureFormat format) { |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 185 | switch (format) { |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 186 | case wgpu::TextureFormat::R8Unorm: |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 187 | return MTLPixelFormatR8Unorm; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 188 | case wgpu::TextureFormat::R8Snorm: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 189 | return MTLPixelFormatR8Snorm; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 190 | case wgpu::TextureFormat::R8Uint: |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 191 | return MTLPixelFormatR8Uint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 192 | case wgpu::TextureFormat::R8Sint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 193 | return MTLPixelFormatR8Sint; |
| 194 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 195 | case wgpu::TextureFormat::R16Uint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 196 | return MTLPixelFormatR16Uint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 197 | case wgpu::TextureFormat::R16Sint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 198 | return MTLPixelFormatR16Sint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 199 | case wgpu::TextureFormat::R16Float: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 200 | return MTLPixelFormatR16Float; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 201 | case wgpu::TextureFormat::RG8Unorm: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 202 | return MTLPixelFormatRG8Unorm; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 203 | case wgpu::TextureFormat::RG8Snorm: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 204 | return MTLPixelFormatRG8Snorm; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 205 | case wgpu::TextureFormat::RG8Uint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 206 | return MTLPixelFormatRG8Uint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 207 | case wgpu::TextureFormat::RG8Sint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 208 | return MTLPixelFormatRG8Sint; |
| 209 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 210 | case wgpu::TextureFormat::R32Uint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 211 | return MTLPixelFormatR32Uint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 212 | case wgpu::TextureFormat::R32Sint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 213 | return MTLPixelFormatR32Sint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 214 | case wgpu::TextureFormat::R32Float: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 215 | return MTLPixelFormatR32Float; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 216 | case wgpu::TextureFormat::RG16Uint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 217 | return MTLPixelFormatRG16Uint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 218 | case wgpu::TextureFormat::RG16Sint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 219 | return MTLPixelFormatRG16Sint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 220 | case wgpu::TextureFormat::RG16Float: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 221 | return MTLPixelFormatRG16Float; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 222 | case wgpu::TextureFormat::RGBA8Unorm: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 223 | return MTLPixelFormatRGBA8Unorm; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 224 | case wgpu::TextureFormat::RGBA8UnormSrgb: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 225 | return MTLPixelFormatRGBA8Unorm_sRGB; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 226 | case wgpu::TextureFormat::RGBA8Snorm: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 227 | return MTLPixelFormatRGBA8Snorm; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 228 | case wgpu::TextureFormat::RGBA8Uint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 229 | return MTLPixelFormatRGBA8Uint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 230 | case wgpu::TextureFormat::RGBA8Sint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 231 | return MTLPixelFormatRGBA8Sint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 232 | case wgpu::TextureFormat::BGRA8Unorm: |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 233 | return MTLPixelFormatBGRA8Unorm; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 234 | case wgpu::TextureFormat::BGRA8UnormSrgb: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 235 | return MTLPixelFormatBGRA8Unorm_sRGB; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 236 | case wgpu::TextureFormat::RGB10A2Unorm: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 237 | return MTLPixelFormatRGB10A2Unorm; |
Corentin Wallez | 2f6e4ec | 2020-08-19 21:51:20 +0000 | [diff] [blame] | 238 | case wgpu::TextureFormat::RG11B10Ufloat: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 239 | return MTLPixelFormatRG11B10Float; |
Corentin Wallez | 2f6e4ec | 2020-08-19 21:51:20 +0000 | [diff] [blame] | 240 | case wgpu::TextureFormat::RGB9E5Ufloat: |
| 241 | return MTLPixelFormatRGB9E5Float; |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 242 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 243 | case wgpu::TextureFormat::RG32Uint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 244 | return MTLPixelFormatRG32Uint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 245 | case wgpu::TextureFormat::RG32Sint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 246 | return MTLPixelFormatRG32Sint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 247 | case wgpu::TextureFormat::RG32Float: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 248 | return MTLPixelFormatRG32Float; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 249 | case wgpu::TextureFormat::RGBA16Uint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 250 | return MTLPixelFormatRGBA16Uint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 251 | case wgpu::TextureFormat::RGBA16Sint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 252 | return MTLPixelFormatRGBA16Sint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 253 | case wgpu::TextureFormat::RGBA16Float: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 254 | return MTLPixelFormatRGBA16Float; |
| 255 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 256 | case wgpu::TextureFormat::RGBA32Uint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 257 | return MTLPixelFormatRGBA32Uint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 258 | case wgpu::TextureFormat::RGBA32Sint: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 259 | return MTLPixelFormatRGBA32Sint; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 260 | case wgpu::TextureFormat::RGBA32Float: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 261 | return MTLPixelFormatRGBA32Float; |
| 262 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 263 | case wgpu::TextureFormat::Depth32Float: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 264 | return MTLPixelFormatDepth32Float; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 265 | case wgpu::TextureFormat::Depth24Plus: |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 266 | return MTLPixelFormatDepth32Float; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 267 | case wgpu::TextureFormat::Depth24PlusStencil8: |
Li Hao | 538d8d5 | 2022-01-05 01:31:16 +0000 | [diff] [blame] | 268 | case wgpu::TextureFormat::Depth32FloatStencil8: |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 269 | return MTLPixelFormatDepth32Float_Stencil8; |
Dawn Autoroller | d0effc0 | 2021-11-03 22:48:34 +0000 | [diff] [blame] | 270 | case wgpu::TextureFormat::Depth16Unorm: |
| 271 | if (@available(macOS 10.12, iOS 13.0, *)) { |
| 272 | return MTLPixelFormatDepth16Unorm; |
| 273 | } else { |
| 274 | // TODO (dawn:1181): Allow non-conformant implementation on macOS 10.11 |
| 275 | UNREACHABLE(); |
| 276 | } |
Corentin Wallez | 7843076 | 2019-07-08 09:28:51 +0000 | [diff] [blame] | 277 | |
Corentin Wallez | b629c50 | 2019-10-08 07:44:21 +0000 | [diff] [blame] | 278 | #if defined(DAWN_PLATFORM_MACOS) |
Li Hao | 538d8d5 | 2022-01-05 01:31:16 +0000 | [diff] [blame] | 279 | case wgpu::TextureFormat::Depth24UnormStencil8: |
| 280 | return MTLPixelFormatDepth24Unorm_Stencil8; |
| 281 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 282 | case wgpu::TextureFormat::BC1RGBAUnorm: |
Jiawei Shao | 5580970 | 2019-07-17 00:00:10 +0000 | [diff] [blame] | 283 | return MTLPixelFormatBC1_RGBA; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 284 | case wgpu::TextureFormat::BC1RGBAUnormSrgb: |
Jiawei Shao | 5580970 | 2019-07-17 00:00:10 +0000 | [diff] [blame] | 285 | return MTLPixelFormatBC1_RGBA_sRGB; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 286 | case wgpu::TextureFormat::BC2RGBAUnorm: |
Jiawei Shao | 5580970 | 2019-07-17 00:00:10 +0000 | [diff] [blame] | 287 | return MTLPixelFormatBC2_RGBA; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 288 | case wgpu::TextureFormat::BC2RGBAUnormSrgb: |
Jiawei Shao | 5580970 | 2019-07-17 00:00:10 +0000 | [diff] [blame] | 289 | return MTLPixelFormatBC2_RGBA_sRGB; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 290 | case wgpu::TextureFormat::BC3RGBAUnorm: |
Jiawei Shao | 5580970 | 2019-07-17 00:00:10 +0000 | [diff] [blame] | 291 | return MTLPixelFormatBC3_RGBA; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 292 | case wgpu::TextureFormat::BC3RGBAUnormSrgb: |
Jiawei Shao | 5580970 | 2019-07-17 00:00:10 +0000 | [diff] [blame] | 293 | return MTLPixelFormatBC3_RGBA_sRGB; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 294 | case wgpu::TextureFormat::BC4RSnorm: |
Jiawei Shao | 5580970 | 2019-07-17 00:00:10 +0000 | [diff] [blame] | 295 | return MTLPixelFormatBC4_RSnorm; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 296 | case wgpu::TextureFormat::BC4RUnorm: |
Jiawei Shao | 5580970 | 2019-07-17 00:00:10 +0000 | [diff] [blame] | 297 | return MTLPixelFormatBC4_RUnorm; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 298 | case wgpu::TextureFormat::BC5RGSnorm: |
Jiawei Shao | ea2d558 | 2019-07-10 23:58:13 +0000 | [diff] [blame] | 299 | return MTLPixelFormatBC5_RGSnorm; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 300 | case wgpu::TextureFormat::BC5RGUnorm: |
Jiawei Shao | ea2d558 | 2019-07-10 23:58:13 +0000 | [diff] [blame] | 301 | return MTLPixelFormatBC5_RGUnorm; |
Corentin Wallez | 498d5ea | 2020-09-10 08:48:57 +0000 | [diff] [blame] | 302 | case wgpu::TextureFormat::BC6HRGBFloat: |
Jiawei Shao | 5580970 | 2019-07-17 00:00:10 +0000 | [diff] [blame] | 303 | return MTLPixelFormatBC6H_RGBFloat; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 304 | case wgpu::TextureFormat::BC6HRGBUfloat: |
Jiawei Shao | 5580970 | 2019-07-17 00:00:10 +0000 | [diff] [blame] | 305 | return MTLPixelFormatBC6H_RGBUfloat; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 306 | case wgpu::TextureFormat::BC7RGBAUnorm: |
Jiawei Shao | 5580970 | 2019-07-17 00:00:10 +0000 | [diff] [blame] | 307 | return MTLPixelFormatBC7_RGBAUnorm; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 308 | case wgpu::TextureFormat::BC7RGBAUnormSrgb: |
Jiawei Shao | 5580970 | 2019-07-17 00:00:10 +0000 | [diff] [blame] | 309 | return MTLPixelFormatBC7_RGBAUnorm_sRGB; |
Loko Kung | c7226a7 | 2021-08-31 00:15:45 +0000 | [diff] [blame] | 310 | #else |
Li Hao | 538d8d5 | 2022-01-05 01:31:16 +0000 | [diff] [blame] | 311 | case wgpu::TextureFormat::Depth24UnormStencil8: |
| 312 | |
Loko Kung | c7226a7 | 2021-08-31 00:15:45 +0000 | [diff] [blame] | 313 | case wgpu::TextureFormat::BC1RGBAUnorm: |
| 314 | case wgpu::TextureFormat::BC1RGBAUnormSrgb: |
| 315 | case wgpu::TextureFormat::BC2RGBAUnorm: |
| 316 | case wgpu::TextureFormat::BC2RGBAUnormSrgb: |
| 317 | case wgpu::TextureFormat::BC3RGBAUnorm: |
| 318 | case wgpu::TextureFormat::BC3RGBAUnormSrgb: |
| 319 | case wgpu::TextureFormat::BC4RSnorm: |
| 320 | case wgpu::TextureFormat::BC4RUnorm: |
| 321 | case wgpu::TextureFormat::BC5RGSnorm: |
| 322 | case wgpu::TextureFormat::BC5RGUnorm: |
| 323 | case wgpu::TextureFormat::BC6HRGBFloat: |
| 324 | case wgpu::TextureFormat::BC6HRGBUfloat: |
| 325 | case wgpu::TextureFormat::BC7RGBAUnorm: |
| 326 | case wgpu::TextureFormat::BC7RGBAUnormSrgb: |
Corentin Wallez | b629c50 | 2019-10-08 07:44:21 +0000 | [diff] [blame] | 327 | #endif |
Jiawei Shao | ea2d558 | 2019-07-10 23:58:13 +0000 | [diff] [blame] | 328 | |
Loko Kung | c7226a7 | 2021-08-31 00:15:45 +0000 | [diff] [blame] | 329 | case wgpu::TextureFormat::R8BG8Biplanar420Unorm: |
| 330 | |
| 331 | case wgpu::TextureFormat::ETC2RGB8Unorm: |
| 332 | case wgpu::TextureFormat::ETC2RGB8UnormSrgb: |
| 333 | case wgpu::TextureFormat::ETC2RGB8A1Unorm: |
| 334 | case wgpu::TextureFormat::ETC2RGB8A1UnormSrgb: |
| 335 | case wgpu::TextureFormat::ETC2RGBA8Unorm: |
| 336 | case wgpu::TextureFormat::ETC2RGBA8UnormSrgb: |
| 337 | case wgpu::TextureFormat::EACR11Unorm: |
| 338 | case wgpu::TextureFormat::EACR11Snorm: |
| 339 | case wgpu::TextureFormat::EACRG11Unorm: |
| 340 | case wgpu::TextureFormat::EACRG11Snorm: |
| 341 | |
Loko Kung | 37a8649 | 2021-09-07 18:39:04 +0000 | [diff] [blame] | 342 | case wgpu::TextureFormat::ASTC4x4Unorm: |
| 343 | case wgpu::TextureFormat::ASTC4x4UnormSrgb: |
| 344 | case wgpu::TextureFormat::ASTC5x4Unorm: |
| 345 | case wgpu::TextureFormat::ASTC5x4UnormSrgb: |
| 346 | case wgpu::TextureFormat::ASTC5x5Unorm: |
| 347 | case wgpu::TextureFormat::ASTC5x5UnormSrgb: |
| 348 | case wgpu::TextureFormat::ASTC6x5Unorm: |
| 349 | case wgpu::TextureFormat::ASTC6x5UnormSrgb: |
| 350 | case wgpu::TextureFormat::ASTC6x6Unorm: |
| 351 | case wgpu::TextureFormat::ASTC6x6UnormSrgb: |
| 352 | case wgpu::TextureFormat::ASTC8x5Unorm: |
| 353 | case wgpu::TextureFormat::ASTC8x5UnormSrgb: |
| 354 | case wgpu::TextureFormat::ASTC8x6Unorm: |
| 355 | case wgpu::TextureFormat::ASTC8x6UnormSrgb: |
| 356 | case wgpu::TextureFormat::ASTC8x8Unorm: |
| 357 | case wgpu::TextureFormat::ASTC8x8UnormSrgb: |
| 358 | case wgpu::TextureFormat::ASTC10x5Unorm: |
| 359 | case wgpu::TextureFormat::ASTC10x5UnormSrgb: |
| 360 | case wgpu::TextureFormat::ASTC10x6Unorm: |
| 361 | case wgpu::TextureFormat::ASTC10x6UnormSrgb: |
| 362 | case wgpu::TextureFormat::ASTC10x8Unorm: |
| 363 | case wgpu::TextureFormat::ASTC10x8UnormSrgb: |
| 364 | case wgpu::TextureFormat::ASTC10x10Unorm: |
| 365 | case wgpu::TextureFormat::ASTC10x10UnormSrgb: |
| 366 | case wgpu::TextureFormat::ASTC12x10Unorm: |
| 367 | case wgpu::TextureFormat::ASTC12x10UnormSrgb: |
| 368 | case wgpu::TextureFormat::ASTC12x12Unorm: |
| 369 | case wgpu::TextureFormat::ASTC12x12UnormSrgb: |
| 370 | |
Kai Ninomiya | fa9ca44 | 2021-09-17 18:25:53 +0000 | [diff] [blame] | 371 | // TODO(dawn:666): implement stencil8 |
Loko Kung | c7226a7 | 2021-08-31 00:15:45 +0000 | [diff] [blame] | 372 | case wgpu::TextureFormat::Stencil8: |
| 373 | case wgpu::TextureFormat::Undefined: |
Jiawei Shao | c2750ab | 2019-06-01 02:30:51 +0000 | [diff] [blame] | 374 | UNREACHABLE(); |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 375 | } |
| 376 | } |
| 377 | |
| 378 | MaybeError ValidateIOSurfaceCanBeWrapped(const DeviceBase*, |
| 379 | const TextureDescriptor* descriptor, |
| 380 | IOSurfaceRef ioSurface, |
| 381 | uint32_t plane) { |
| 382 | // IOSurfaceGetPlaneCount can return 0 for non-planar IOSurfaces but we will treat |
| 383 | // non-planar like it is a single plane. |
| 384 | size_t surfacePlaneCount = std::max(size_t(1), IOSurfaceGetPlaneCount(ioSurface)); |
Brandon Jones | eb0d900 | 2021-10-22 17:39:20 +0000 | [diff] [blame] | 385 | DAWN_INVALID_IF(plane >= surfacePlaneCount, |
| 386 | "IOSurface plane (%u) exceeds the surface's plane count (%u).", plane, |
| 387 | surfacePlaneCount); |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 388 | |
Brandon Jones | eb0d900 | 2021-10-22 17:39:20 +0000 | [diff] [blame] | 389 | DAWN_INVALID_IF(descriptor->dimension != wgpu::TextureDimension::e2D, |
| 390 | "Texture dimension (%s) is not %s.", descriptor->dimension, |
| 391 | wgpu::TextureDimension::e2D); |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 392 | |
Brandon Jones | eb0d900 | 2021-10-22 17:39:20 +0000 | [diff] [blame] | 393 | DAWN_INVALID_IF(descriptor->mipLevelCount != 1, "Mip level count (%u) is not 1.", |
| 394 | descriptor->mipLevelCount); |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 395 | |
Brandon Jones | eb0d900 | 2021-10-22 17:39:20 +0000 | [diff] [blame] | 396 | DAWN_INVALID_IF(descriptor->size.depthOrArrayLayers != 1, |
| 397 | "Array layer count (%u) is not 1.", descriptor->size.depthOrArrayLayers); |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 398 | |
Brandon Jones | eb0d900 | 2021-10-22 17:39:20 +0000 | [diff] [blame] | 399 | DAWN_INVALID_IF(descriptor->sampleCount != 1, "Sample count (%u) is not 1.", |
| 400 | descriptor->sampleCount); |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 401 | |
Brandon Jones | eb0d900 | 2021-10-22 17:39:20 +0000 | [diff] [blame] | 402 | uint32_t surfaceWidth = IOSurfaceGetWidthOfPlane(ioSurface, plane); |
| 403 | uint32_t surfaceHeight = IOSurfaceGetHeightOfPlane(ioSurface, plane); |
| 404 | |
| 405 | DAWN_INVALID_IF( |
| 406 | descriptor->size.width != surfaceWidth || descriptor->size.height != surfaceHeight || |
| 407 | descriptor->size.depthOrArrayLayers != 1, |
| 408 | "IOSurface size (width: %u, height %u, depth: 1) doesn't match descriptor size %s.", |
| 409 | surfaceWidth, surfaceHeight, &descriptor->size); |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 410 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 411 | wgpu::TextureFormat ioSurfaceFormat; |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 412 | DAWN_TRY_ASSIGN(ioSurfaceFormat, |
| 413 | GetFormatEquivalentToIOSurfaceFormat(IOSurfaceGetPixelFormat(ioSurface))); |
Brandon Jones | eb0d900 | 2021-10-22 17:39:20 +0000 | [diff] [blame] | 414 | DAWN_INVALID_IF(descriptor->format != ioSurfaceFormat, |
| 415 | "IOSurface format (%s) doesn't match the descriptor format (%s).", |
| 416 | ioSurfaceFormat, descriptor->format); |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 417 | |
| 418 | return {}; |
| 419 | } |
| 420 | |
Austin Eng | 0eff598 | 2021-07-27 19:59:58 +0000 | [diff] [blame] | 421 | NSRef<MTLTextureDescriptor> Texture::CreateMetalTextureDescriptor() const { |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 422 | NSRef<MTLTextureDescriptor> mtlDescRef = AcquireNSRef([MTLTextureDescriptor new]); |
| 423 | MTLTextureDescriptor* mtlDesc = mtlDescRef.Get(); |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 424 | |
Austin Eng | 0eff598 | 2021-07-27 19:59:58 +0000 | [diff] [blame] | 425 | mtlDesc.width = GetWidth(); |
| 426 | mtlDesc.height = GetHeight(); |
| 427 | mtlDesc.sampleCount = GetSampleCount(); |
Yan | cf0e4fc | 2022-01-06 09:01:58 +0000 | [diff] [blame^] | 428 | // Metal only allows format reinterpretation to happen on swizzle pattern or conversion |
| 429 | // between linear space and sRGB. For example, creating bgra8Unorm texture view on |
| 430 | // rgba8Unorm texture or creating rgba8Unorm_srgb texture view on rgab8Unorm texture. |
| 431 | // TODO: add MTLTextureUsagePixelFormatView when needed when we support other format |
Corentin Wallez | caec4ab | 2020-08-18 15:39:06 +0000 | [diff] [blame] | 432 | // reinterpretation. |
Austin Eng | 0eff598 | 2021-07-27 19:59:58 +0000 | [diff] [blame] | 433 | mtlDesc.usage = MetalTextureUsage(GetFormat(), GetInternalUsage(), GetSampleCount()); |
| 434 | mtlDesc.pixelFormat = MetalPixelFormat(GetFormat().format); |
| 435 | mtlDesc.mipmapLevelCount = GetNumMipLevels(); |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 436 | mtlDesc.storageMode = MTLStorageModePrivate; |
| 437 | |
Corentin Wallez | 8a5325c | 2020-06-15 09:57:51 +0000 | [diff] [blame] | 438 | // Choose the correct MTLTextureType and paper over differences in how the array layer count |
| 439 | // is specified. |
Austin Eng | 0eff598 | 2021-07-27 19:59:58 +0000 | [diff] [blame] | 440 | switch (GetDimension()) { |
Corentin Wallez | 8a5325c | 2020-06-15 09:57:51 +0000 | [diff] [blame] | 441 | case wgpu::TextureDimension::e2D: |
Austin Eng | 0eff598 | 2021-07-27 19:59:58 +0000 | [diff] [blame] | 442 | mtlDesc.depth = 1; |
| 443 | mtlDesc.arrayLength = GetArrayLayers(); |
| 444 | if (mtlDesc.arrayLength > 1) { |
Corentin Wallez | 8a5325c | 2020-06-15 09:57:51 +0000 | [diff] [blame] | 445 | ASSERT(mtlDesc.sampleCount == 1); |
| 446 | mtlDesc.textureType = MTLTextureType2DArray; |
Austin Eng | 0eff598 | 2021-07-27 19:59:58 +0000 | [diff] [blame] | 447 | } else if (mtlDesc.sampleCount > 1) { |
| 448 | mtlDesc.textureType = MTLTextureType2DMultisample; |
Corentin Wallez | 8a5325c | 2020-06-15 09:57:51 +0000 | [diff] [blame] | 449 | } else { |
Austin Eng | 0eff598 | 2021-07-27 19:59:58 +0000 | [diff] [blame] | 450 | mtlDesc.textureType = MTLTextureType2D; |
Corentin Wallez | 8a5325c | 2020-06-15 09:57:51 +0000 | [diff] [blame] | 451 | } |
| 452 | break; |
Yunchao He | 1b9bcfc | 2021-02-03 16:36:59 +0000 | [diff] [blame] | 453 | case wgpu::TextureDimension::e3D: |
Austin Eng | 0eff598 | 2021-07-27 19:59:58 +0000 | [diff] [blame] | 454 | mtlDesc.depth = GetDepth(); |
| 455 | mtlDesc.arrayLength = 1; |
Yunchao He | 1b9bcfc | 2021-02-03 16:36:59 +0000 | [diff] [blame] | 456 | ASSERT(mtlDesc.sampleCount == 1); |
| 457 | mtlDesc.textureType = MTLTextureType3D; |
| 458 | break; |
Corentin Wallez | 8a5325c | 2020-06-15 09:57:51 +0000 | [diff] [blame] | 459 | |
Corentin Wallez | eec9edf | 2020-09-24 14:56:50 +0000 | [diff] [blame] | 460 | case wgpu::TextureDimension::e1D: |
Corentin Wallez | 8a5325c | 2020-06-15 09:57:51 +0000 | [diff] [blame] | 461 | UNREACHABLE(); |
| 462 | } |
Jiawei Shao | 865cad8 | 2019-04-09 08:04:59 +0000 | [diff] [blame] | 463 | |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 464 | return mtlDescRef; |
Corentin Wallez | 0ba5550 | 2017-06-14 15:46:59 -0400 | [diff] [blame] | 465 | } |
| 466 | |
Corentin Wallez | 50f9958 | 2021-03-31 18:36:32 +0000 | [diff] [blame] | 467 | // static |
| 468 | ResultOrError<Ref<Texture>> Texture::Create(Device* device, |
| 469 | const TextureDescriptor* descriptor) { |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 470 | Ref<Texture> texture = |
| 471 | AcquireRef(new Texture(device, descriptor, TextureState::OwnedInternal)); |
| 472 | DAWN_TRY(texture->InitializeAsInternalTexture(descriptor)); |
| 473 | return texture; |
Corentin Wallez | 50f9958 | 2021-03-31 18:36:32 +0000 | [diff] [blame] | 474 | } |
| 475 | |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 476 | // static |
| 477 | ResultOrError<Ref<Texture>> Texture::CreateFromIOSurface( |
| 478 | Device* device, |
| 479 | const ExternalImageDescriptor* descriptor, |
| 480 | IOSurfaceRef ioSurface, |
| 481 | uint32_t plane) { |
Corentin Wallez | c6d3a84 | 2021-12-03 16:47:18 +0000 | [diff] [blame] | 482 | const TextureDescriptor* textureDescriptor = FromAPI(descriptor->cTextureDescriptor); |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 483 | |
| 484 | Ref<Texture> texture = |
| 485 | AcquireRef(new Texture(device, textureDescriptor, TextureState::OwnedInternal)); |
| 486 | DAWN_TRY(texture->InitializeFromIOSurface(descriptor, textureDescriptor, ioSurface, plane)); |
| 487 | return texture; |
| 488 | } |
| 489 | |
| 490 | // static |
| 491 | Ref<Texture> Texture::CreateWrapping(Device* device, |
| 492 | const TextureDescriptor* descriptor, |
| 493 | NSPRef<id<MTLTexture>> wrapped) { |
| 494 | Ref<Texture> texture = |
| 495 | AcquireRef(new Texture(device, descriptor, TextureState::OwnedInternal)); |
| 496 | texture->InitializeAsWrapping(descriptor, std::move(wrapped)); |
| 497 | return texture; |
| 498 | } |
| 499 | |
| 500 | MaybeError Texture::InitializeAsInternalTexture(const TextureDescriptor* descriptor) { |
| 501 | Device* device = ToBackend(GetDevice()); |
| 502 | |
Austin Eng | 0eff598 | 2021-07-27 19:59:58 +0000 | [diff] [blame] | 503 | NSRef<MTLTextureDescriptor> mtlDesc = CreateMetalTextureDescriptor(); |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 504 | mMtlUsage = [*mtlDesc usage]; |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 505 | mMtlTexture = |
| 506 | AcquireNSPRef([device->GetMTLDevice() newTextureWithDescriptor:mtlDesc.Get()]); |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 507 | |
| 508 | if (mMtlTexture == nil) { |
| 509 | return DAWN_OUT_OF_MEMORY_ERROR("Failed to allocate texture."); |
| 510 | } |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 511 | |
| 512 | if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) { |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 513 | DAWN_TRY(ClearTexture(device->GetPendingCommandContext(), GetAllSubresources(), |
| 514 | TextureBase::ClearValue::NonZero)); |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 515 | } |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 516 | |
| 517 | return {}; |
Corentin Wallez | 0ba5550 | 2017-06-14 15:46:59 -0400 | [diff] [blame] | 518 | } |
| 519 | |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 520 | void Texture::InitializeAsWrapping(const TextureDescriptor* descriptor, |
| 521 | NSPRef<id<MTLTexture>> wrapped) { |
Austin Eng | 0eff598 | 2021-07-27 19:59:58 +0000 | [diff] [blame] | 522 | NSRef<MTLTextureDescriptor> mtlDesc = CreateMetalTextureDescriptor(); |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 523 | mMtlUsage = [*mtlDesc usage]; |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 524 | mMtlTexture = std::move(wrapped); |
Kai Ninomiya | 35bf424 | 2017-07-19 15:41:17 -0700 | [diff] [blame] | 525 | } |
| 526 | |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 527 | MaybeError Texture::InitializeFromIOSurface(const ExternalImageDescriptor* descriptor, |
| 528 | const TextureDescriptor* textureDescriptor, |
| 529 | IOSurfaceRef ioSurface, |
| 530 | uint32_t plane) { |
| 531 | Device* device = ToBackend(GetDevice()); |
| 532 | |
Austin Eng | 0eff598 | 2021-07-27 19:59:58 +0000 | [diff] [blame] | 533 | NSRef<MTLTextureDescriptor> mtlDesc = CreateMetalTextureDescriptor(); |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 534 | [*mtlDesc setStorageMode:kIOSurfaceStorageMode]; |
| 535 | |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 536 | mMtlUsage = [*mtlDesc usage]; |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 537 | mMtlTexture = AcquireNSPRef([device->GetMTLDevice() newTextureWithDescriptor:mtlDesc.Get() |
| 538 | iosurface:ioSurface |
| 539 | plane:plane]); |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 540 | |
Austin Eng | 0b29732 | 2020-09-22 20:10:46 +0000 | [diff] [blame] | 541 | SetIsSubresourceContentInitialized(descriptor->isInitialized, GetAllSubresources()); |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 542 | |
| 543 | return {}; |
Corentin Wallez | 0cdf9e0 | 2019-03-01 12:01:18 +0000 | [diff] [blame] | 544 | } |
| 545 | |
Corentin Wallez | 0ba5550 | 2017-06-14 15:46:59 -0400 | [diff] [blame] | 546 | Texture::~Texture() { |
Natasha Lee | cae68ff | 2019-03-27 22:04:10 +0000 | [diff] [blame] | 547 | } |
| 548 | |
Loko Kung | e9c84c0 | 2021-11-11 01:39:52 +0000 | [diff] [blame] | 549 | void Texture::DestroyImpl() { |
Loko Kung | 6331f95 | 2021-12-01 18:54:40 +0000 | [diff] [blame] | 550 | TextureBase::DestroyImpl(); |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 551 | mMtlTexture = nullptr; |
Corentin Wallez | 0ba5550 | 2017-06-14 15:46:59 -0400 | [diff] [blame] | 552 | } |
| 553 | |
| 554 | id<MTLTexture> Texture::GetMTLTexture() { |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 555 | return mMtlTexture.Get(); |
Corentin Wallez | 0ba5550 | 2017-06-14 15:46:59 -0400 | [diff] [blame] | 556 | } |
| 557 | |
Yan | cf0e4fc | 2022-01-06 09:01:58 +0000 | [diff] [blame^] | 558 | NSPRef<id<MTLTexture>> Texture::CreateFormatView(wgpu::TextureFormat format) { |
| 559 | if (GetFormat().format == format) { |
| 560 | return mMtlTexture; |
| 561 | } |
| 562 | |
| 563 | ASSERT(AllowFormatReinterpretationWithoutFlag(MetalPixelFormat(GetFormat().format), |
| 564 | MetalPixelFormat(format))); |
| 565 | return AcquireNSPRef( |
| 566 | [mMtlTexture.Get() newTextureViewWithPixelFormat:MetalPixelFormat(format)]); |
| 567 | } |
| 568 | |
Austin Eng | 26468c4 | 2021-05-08 16:01:16 +0000 | [diff] [blame] | 569 | MaybeError Texture::ClearTexture(CommandRecordingContext* commandContext, |
| 570 | const SubresourceRange& range, |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 571 | TextureBase::ClearValue clearValue) { |
| 572 | Device* device = ToBackend(GetDevice()); |
| 573 | |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 574 | const uint8_t clearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0 : 1; |
| 575 | const double dClearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0.0 : 1.0; |
| 576 | |
Austin Eng | 75c5067 | 2021-06-24 02:01:46 +0000 | [diff] [blame] | 577 | if ((mMtlUsage & MTLTextureUsageRenderTarget) != 0) { |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 578 | ASSERT(GetFormat().isRenderable); |
| 579 | |
| 580 | // End the blit encoder if it is open. |
| 581 | commandContext->EndBlit(); |
| 582 | |
| 583 | if (GetFormat().HasDepthOrStencil()) { |
| 584 | // Create a render pass to clear each subresource. |
Yunchao He | 5fafb49 | 2020-06-12 00:37:31 +0000 | [diff] [blame] | 585 | for (uint32_t level = range.baseMipLevel; |
| 586 | level < range.baseMipLevel + range.levelCount; ++level) { |
| 587 | for (uint32_t arrayLayer = range.baseArrayLayer; |
| 588 | arrayLayer < range.baseArrayLayer + range.layerCount; arrayLayer++) { |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 589 | if (clearValue == TextureBase::ClearValue::Zero && |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 590 | IsSubresourceContentInitialized(SubresourceRange::SingleMipAndLayer( |
| 591 | level, arrayLayer, range.aspects))) { |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 592 | // Skip lazy clears if already initialized. |
| 593 | continue; |
| 594 | } |
| 595 | |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 596 | // Note that this creates a descriptor that's autoreleased so we don't use |
| 597 | // AcquireNSRef |
| 598 | NSRef<MTLRenderPassDescriptor> descriptorRef = |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 599 | [MTLRenderPassDescriptor renderPassDescriptor]; |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 600 | MTLRenderPassDescriptor* descriptor = descriptorRef.Get(); |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 601 | |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 602 | // At least one aspect needs clearing. Iterate the aspects individually to |
| 603 | // determine which to clear. |
| 604 | for (Aspect aspect : IterateEnumMask(range.aspects)) { |
| 605 | if (clearValue == TextureBase::ClearValue::Zero && |
| 606 | IsSubresourceContentInitialized(SubresourceRange::SingleMipAndLayer( |
| 607 | level, arrayLayer, aspect))) { |
| 608 | // Skip lazy clears if already initialized. |
| 609 | continue; |
| 610 | } |
| 611 | |
Austin Eng | fd783ce | 2021-05-18 21:51:33 +0000 | [diff] [blame] | 612 | ASSERT(GetDimension() == wgpu::TextureDimension::e2D); |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 613 | switch (aspect) { |
| 614 | case Aspect::Depth: |
| 615 | descriptor.depthAttachment.texture = GetMTLTexture(); |
Austin Eng | 600f6f5 | 2020-12-03 16:55:53 +0000 | [diff] [blame] | 616 | descriptor.depthAttachment.level = level; |
| 617 | descriptor.depthAttachment.slice = arrayLayer; |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 618 | descriptor.depthAttachment.loadAction = MTLLoadActionClear; |
| 619 | descriptor.depthAttachment.storeAction = MTLStoreActionStore; |
| 620 | descriptor.depthAttachment.clearDepth = dClearColor; |
| 621 | break; |
| 622 | case Aspect::Stencil: |
| 623 | descriptor.stencilAttachment.texture = GetMTLTexture(); |
Austin Eng | 600f6f5 | 2020-12-03 16:55:53 +0000 | [diff] [blame] | 624 | descriptor.stencilAttachment.level = level; |
| 625 | descriptor.stencilAttachment.slice = arrayLayer; |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 626 | descriptor.stencilAttachment.loadAction = MTLLoadActionClear; |
| 627 | descriptor.stencilAttachment.storeAction = MTLStoreActionStore; |
| 628 | descriptor.stencilAttachment.clearStencil = |
| 629 | static_cast<uint32_t>(clearColor); |
| 630 | break; |
| 631 | default: |
| 632 | UNREACHABLE(); |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 633 | } |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 634 | } |
| 635 | |
| 636 | commandContext->BeginRender(descriptor); |
| 637 | commandContext->EndRender(); |
| 638 | } |
| 639 | } |
| 640 | } else { |
| 641 | ASSERT(GetFormat().IsColor()); |
Yunchao He | 5fafb49 | 2020-06-12 00:37:31 +0000 | [diff] [blame] | 642 | for (uint32_t level = range.baseMipLevel; |
| 643 | level < range.baseMipLevel + range.levelCount; ++level) { |
Corentin Wallez | da6dccd | 2020-05-29 07:37:48 +0000 | [diff] [blame] | 644 | // Create multiple render passes with each subresource as a color attachment to |
| 645 | // clear them all. Only do this for array layers to ensure all attachments have |
| 646 | // the same size. |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 647 | NSRef<MTLRenderPassDescriptor> descriptor; |
Corentin Wallez | da6dccd | 2020-05-29 07:37:48 +0000 | [diff] [blame] | 648 | uint32_t attachment = 0; |
| 649 | |
Austin Eng | fd783ce | 2021-05-18 21:51:33 +0000 | [diff] [blame] | 650 | uint32_t numZSlices = GetMipLevelVirtualSize(level).depthOrArrayLayers; |
| 651 | |
Yunchao He | 5fafb49 | 2020-06-12 00:37:31 +0000 | [diff] [blame] | 652 | for (uint32_t arrayLayer = range.baseArrayLayer; |
| 653 | arrayLayer < range.baseArrayLayer + range.layerCount; arrayLayer++) { |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 654 | if (clearValue == TextureBase::ClearValue::Zero && |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 655 | IsSubresourceContentInitialized(SubresourceRange::SingleMipAndLayer( |
| 656 | level, arrayLayer, Aspect::Color))) { |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 657 | // Skip lazy clears if already initialized. |
| 658 | continue; |
| 659 | } |
| 660 | |
Austin Eng | fd783ce | 2021-05-18 21:51:33 +0000 | [diff] [blame] | 661 | for (uint32_t z = 0; z < numZSlices; ++z) { |
| 662 | if (descriptor == nullptr) { |
| 663 | // Note that this creates a descriptor that's autoreleased so we |
| 664 | // don't use AcquireNSRef |
| 665 | descriptor = [MTLRenderPassDescriptor renderPassDescriptor]; |
| 666 | } |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 667 | |
Austin Eng | fd783ce | 2021-05-18 21:51:33 +0000 | [diff] [blame] | 668 | [*descriptor colorAttachments][attachment].texture = GetMTLTexture(); |
| 669 | [*descriptor colorAttachments][attachment].loadAction = |
| 670 | MTLLoadActionClear; |
| 671 | [*descriptor colorAttachments][attachment].storeAction = |
| 672 | MTLStoreActionStore; |
| 673 | [*descriptor colorAttachments][attachment].clearColor = |
| 674 | MTLClearColorMake(dClearColor, dClearColor, dClearColor, |
| 675 | dClearColor); |
| 676 | [*descriptor colorAttachments][attachment].level = level; |
| 677 | [*descriptor colorAttachments][attachment].slice = arrayLayer; |
| 678 | [*descriptor colorAttachments][attachment].depthPlane = z; |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 679 | |
Austin Eng | fd783ce | 2021-05-18 21:51:33 +0000 | [diff] [blame] | 680 | attachment++; |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 681 | |
Austin Eng | fd783ce | 2021-05-18 21:51:33 +0000 | [diff] [blame] | 682 | if (attachment == kMaxColorAttachments) { |
| 683 | attachment = 0; |
| 684 | commandContext->BeginRender(descriptor.Get()); |
| 685 | commandContext->EndRender(); |
| 686 | descriptor = nullptr; |
| 687 | } |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 688 | } |
| 689 | } |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 690 | |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 691 | if (descriptor != nullptr) { |
| 692 | commandContext->BeginRender(descriptor.Get()); |
Corentin Wallez | da6dccd | 2020-05-29 07:37:48 +0000 | [diff] [blame] | 693 | commandContext->EndRender(); |
| 694 | } |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 695 | } |
| 696 | } |
| 697 | } else { |
Yunchao He | 5fafb49 | 2020-06-12 00:37:31 +0000 | [diff] [blame] | 698 | Extent3D largestMipSize = GetMipLevelVirtualSize(range.baseMipLevel); |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 699 | |
| 700 | // Encode a buffer to texture copy to clear each subresource. |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 701 | for (Aspect aspect : IterateEnumMask(range.aspects)) { |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 702 | // Compute the buffer size big enough to fill the largest mip. |
| 703 | const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(aspect).block; |
| 704 | |
| 705 | // Metal validation layers: sourceBytesPerRow must be at least 64. |
| 706 | uint32_t largestMipBytesPerRow = |
| 707 | std::max((largestMipSize.width / blockInfo.width) * blockInfo.byteSize, 64u); |
| 708 | |
| 709 | // Metal validation layers: sourceBytesPerImage must be at least 512. |
| 710 | uint64_t largestMipBytesPerImage = |
| 711 | std::max(static_cast<uint64_t>(largestMipBytesPerRow) * |
| 712 | (largestMipSize.height / blockInfo.height), |
| 713 | 512llu); |
| 714 | |
| 715 | uint64_t bufferSize = largestMipBytesPerImage * largestMipSize.depthOrArrayLayers; |
| 716 | |
| 717 | if (bufferSize > std::numeric_limits<NSUInteger>::max()) { |
| 718 | return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer."); |
| 719 | } |
| 720 | |
| 721 | DynamicUploader* uploader = device->GetDynamicUploader(); |
| 722 | UploadHandle uploadHandle; |
| 723 | DAWN_TRY_ASSIGN(uploadHandle, |
| 724 | uploader->Allocate(bufferSize, device->GetPendingCommandSerial(), |
| 725 | blockInfo.byteSize)); |
| 726 | memset(uploadHandle.mappedBuffer, clearColor, bufferSize); |
| 727 | |
| 728 | id<MTLBuffer> uploadBuffer = |
| 729 | ToBackend(uploadHandle.stagingBuffer)->GetBufferHandle(); |
| 730 | |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 731 | for (uint32_t level = range.baseMipLevel; |
| 732 | level < range.baseMipLevel + range.levelCount; ++level) { |
| 733 | Extent3D virtualSize = GetMipLevelVirtualSize(level); |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 734 | |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 735 | for (uint32_t arrayLayer = range.baseArrayLayer; |
| 736 | arrayLayer < range.baseArrayLayer + range.layerCount; ++arrayLayer) { |
| 737 | if (clearValue == TextureBase::ClearValue::Zero && |
| 738 | IsSubresourceContentInitialized( |
| 739 | SubresourceRange::SingleMipAndLayer(level, arrayLayer, aspect))) { |
| 740 | // Skip lazy clears if already initialized. |
| 741 | continue; |
| 742 | } |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 743 | |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 744 | MTLBlitOption blitOption = ComputeMTLBlitOption(GetFormat(), aspect); |
Austin Eng | 3cd8c43 | 2021-06-01 21:25:33 +0000 | [diff] [blame] | 745 | [commandContext->EnsureBlit() |
| 746 | copyFromBuffer:uploadBuffer |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 747 | sourceOffset:uploadHandle.startOffset |
| 748 | sourceBytesPerRow:largestMipBytesPerRow |
| 749 | sourceBytesPerImage:largestMipBytesPerImage |
| 750 | sourceSize:MTLSizeMake(virtualSize.width, virtualSize.height, |
Austin Eng | fd783ce | 2021-05-18 21:51:33 +0000 | [diff] [blame] | 751 | virtualSize.depthOrArrayLayers) |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 752 | toTexture:GetMTLTexture() |
| 753 | destinationSlice:arrayLayer |
| 754 | destinationLevel:level |
| 755 | destinationOrigin:MTLOriginMake(0, 0, 0) |
Austin Eng | 2cf5a08 | 2020-08-06 17:00:29 +0000 | [diff] [blame] | 756 | options:blitOption]; |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 757 | } |
| 758 | } |
| 759 | } |
| 760 | } |
| 761 | |
| 762 | if (clearValue == TextureBase::ClearValue::Zero) { |
Yunchao He | 5fafb49 | 2020-06-12 00:37:31 +0000 | [diff] [blame] | 763 | SetIsSubresourceContentInitialized(true, range); |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 764 | device->IncrementLazyClearCountForTesting(); |
| 765 | } |
| 766 | return {}; |
| 767 | } |
| 768 | |
Austin Eng | 26468c4 | 2021-05-08 16:01:16 +0000 | [diff] [blame] | 769 | void Texture::EnsureSubresourceContentInitialized(CommandRecordingContext* commandContext, |
| 770 | const SubresourceRange& range) { |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 771 | if (!GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) { |
| 772 | return; |
| 773 | } |
Yunchao He | 5fafb49 | 2020-06-12 00:37:31 +0000 | [diff] [blame] | 774 | if (!IsSubresourceContentInitialized(range)) { |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 775 | // If subresource has not been initialized, clear it to black as it could |
| 776 | // contain dirty bits from recycled memory |
Austin Eng | 26468c4 | 2021-05-08 16:01:16 +0000 | [diff] [blame] | 777 | GetDevice()->ConsumedError( |
| 778 | ClearTexture(commandContext, range, TextureBase::ClearValue::Zero)); |
Austin Eng | 0d66198 | 2020-01-16 00:12:10 +0000 | [diff] [blame] | 779 | } |
| 780 | } |
| 781 | |
Corentin Wallez | 50f9958 | 2021-03-31 18:36:32 +0000 | [diff] [blame] | 782 | // static |
| 783 | ResultOrError<Ref<TextureView>> TextureView::Create(TextureBase* texture, |
| 784 | const TextureViewDescriptor* descriptor) { |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 785 | Ref<TextureView> view = AcquireRef(new TextureView(texture, descriptor)); |
| 786 | DAWN_TRY(view->Initialize(descriptor)); |
| 787 | return view; |
Corentin Wallez | 50f9958 | 2021-03-31 18:36:32 +0000 | [diff] [blame] | 788 | } |
| 789 | |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 790 | MaybeError TextureView::Initialize(const TextureViewDescriptor* descriptor) { |
| 791 | Texture* texture = ToBackend(GetTexture()); |
Austin Eng | da3c5ef | 2021-07-29 21:49:47 +0000 | [diff] [blame] | 792 | |
| 793 | // Texture could be destroyed by the time we make a view. |
| 794 | if (GetTexture()->GetTextureState() == Texture::TextureState::Destroyed) { |
| 795 | return {}; |
| 796 | } |
| 797 | |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 798 | id<MTLTexture> mtlTexture = texture->GetMTLTexture(); |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 799 | |
Austin Eng | 0eff598 | 2021-07-27 19:59:58 +0000 | [diff] [blame] | 800 | if (!UsageNeedsTextureView(texture->GetInternalUsage())) { |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 801 | mMtlTextureView = nullptr; |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 802 | } else if (!RequiresCreatingNewTextureView(texture, descriptor)) { |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 803 | mMtlTextureView = mtlTexture; |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 804 | } else { |
| 805 | MTLPixelFormat format = MetalPixelFormat(descriptor->format); |
Austin Eng | a0f1725 | 2020-11-04 15:27:11 +0000 | [diff] [blame] | 806 | if (descriptor->aspect == wgpu::TextureAspect::StencilOnly) { |
| 807 | if (@available(macOS 10.12, iOS 10.0, *)) { |
Li Hao | 538d8d5 | 2022-01-05 01:31:16 +0000 | [diff] [blame] | 808 | if (format == MTLPixelFormatDepth32Float_Stencil8) { |
| 809 | format = MTLPixelFormatX32_Stencil8; |
| 810 | } |
| 811 | #if defined(DAWN_PLATFORM_MACOS) |
| 812 | else if (format == MTLPixelFormatDepth24Unorm_Stencil8) { |
| 813 | format = MTLPixelFormatX24_Stencil8; |
| 814 | } |
| 815 | #endif |
| 816 | else { |
| 817 | UNREACHABLE(); |
| 818 | } |
Austin Eng | a0f1725 | 2020-11-04 15:27:11 +0000 | [diff] [blame] | 819 | } else { |
| 820 | // TODO(enga): Add a workaround to back combined depth/stencil textures |
| 821 | // with Sampled usage using two separate textures. |
| 822 | // Or, consider always using the workaround for D32S8. |
| 823 | GetDevice()->ConsumedError( |
| 824 | DAWN_DEVICE_LOST_ERROR("Cannot create stencil-only texture view of " |
| 825 | "combined depth/stencil format.")); |
| 826 | } |
| 827 | } |
| 828 | |
Jiawei Shao | 865cad8 | 2019-04-09 08:04:59 +0000 | [diff] [blame] | 829 | MTLTextureType textureViewType = |
| 830 | MetalTextureViewType(descriptor->dimension, texture->GetSampleCount()); |
Jiawei Shao | 2030166 | 2019-02-21 00:45:19 +0000 | [diff] [blame] | 831 | auto mipLevelRange = NSMakeRange(descriptor->baseMipLevel, descriptor->mipLevelCount); |
| 832 | auto arrayLayerRange = |
| 833 | NSMakeRange(descriptor->baseArrayLayer, descriptor->arrayLayerCount); |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 834 | |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 835 | mMtlTextureView = |
| 836 | AcquireNSPRef([mtlTexture newTextureViewWithPixelFormat:format |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 837 | textureType:textureViewType |
| 838 | levels:mipLevelRange |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 839 | slices:arrayLayerRange]); |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 840 | if (mMtlTextureView == nil) { |
| 841 | return DAWN_INTERNAL_ERROR("Failed to create MTLTexture view."); |
| 842 | } |
Jiawei Shao | 5dee56f | 2018-12-29 10:47:28 +0000 | [diff] [blame] | 843 | } |
Corentin Wallez | 03f9437 | 2021-07-21 09:34:28 +0000 | [diff] [blame] | 844 | |
| 845 | return {}; |
Corentin Wallez | 0ba5550 | 2017-06-14 15:46:59 -0400 | [diff] [blame] | 846 | } |
Corentin Wallez | f58d84d | 2017-11-24 14:12:44 -0500 | [diff] [blame] | 847 | |
Jiawei Shao | e8d12b4 | 2018-10-26 06:29:38 +0000 | [diff] [blame] | 848 | id<MTLTexture> TextureView::GetMTLTexture() { |
Corentin Wallez | 0055d95 | 2020-11-16 23:07:56 +0000 | [diff] [blame] | 849 | ASSERT(mMtlTextureView != nullptr); |
| 850 | return mMtlTextureView.Get(); |
Jiawei Shao | e8d12b4 | 2018-10-26 06:29:38 +0000 | [diff] [blame] | 851 | } |
Corentin Wallez | 49a65d0 | 2018-07-24 16:45:45 +0200 | [diff] [blame] | 852 | }} // namespace dawn_native::metal |