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