blob: 9d7701b329aa7320d5ca844aa46bb74ac94d0e19 [file] [log] [blame]
Corentin Wallez4a9ef4e2018-07-18 11:40:26 +02001// Copyright 2017 The Dawn Authors
Corentin Wallez0ba55502017-06-14 15:46:59 -04002//
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 Wallezd37523f2018-07-24 13:53:51 +020015#include "dawn_native/metal/TextureMTL.h"
Corentin Wallez0ba55502017-06-14 15:46:59 -040016
Corentin Wallezb495e482019-09-18 04:32:52 +000017#include "common/Platform.h"
Corentin Wallezd37523f2018-07-24 13:53:51 +020018#include "dawn_native/metal/DeviceMTL.h"
Corentin Wallez0ba55502017-06-14 15:46:59 -040019
Corentin Wallez49a65d02018-07-24 16:45:45 +020020namespace dawn_native { namespace metal {
Corentin Wallez8308b1c2017-07-03 23:02:49 -040021
Austin Eng476e5cb2017-08-03 12:17:14 -040022 namespace {
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000023 bool UsageNeedsTextureView(wgpu::TextureUsage usage) {
24 constexpr wgpu::TextureUsage kUsageNeedsTextureView =
25 wgpu::TextureUsage::Storage | wgpu::TextureUsage::Sampled;
Jiawei Shao5dee56f2018-12-29 10:47:28 +000026 return usage & kUsageNeedsTextureView;
27 }
28
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000029 MTLTextureUsage MetalTextureUsage(wgpu::TextureUsage usage) {
Corentin Wallezf58d84d2017-11-24 14:12:44 -050030 MTLTextureUsage result = MTLTextureUsageUnknown; // This is 0
Corentin Wallez8308b1c2017-07-03 23:02:49 -040031
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000032 if (usage & (wgpu::TextureUsage::Storage)) {
Corentin Wallez8308b1c2017-07-03 23:02:49 -040033 result |= MTLTextureUsageShaderWrite | MTLTextureUsageShaderRead;
34 }
35
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000036 if (usage & (wgpu::TextureUsage::Sampled)) {
Corentin Wallez8308b1c2017-07-03 23:02:49 -040037 result |= MTLTextureUsageShaderRead;
38 }
39
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000040 if (usage & (wgpu::TextureUsage::OutputAttachment)) {
Corentin Wallez8308b1c2017-07-03 23:02:49 -040041 result |= MTLTextureUsageRenderTarget;
42 }
43
Jiawei Shao5dee56f2018-12-29 10:47:28 +000044 if (UsageNeedsTextureView(usage)) {
45 result |= MTLTextureUsagePixelFormatView;
46 }
Jiawei Shaoe8d12b42018-10-26 06:29:38 +000047
Corentin Wallez8308b1c2017-07-03 23:02:49 -040048 return result;
49 }
50
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000051 MTLTextureType MetalTextureType(wgpu::TextureDimension dimension,
Jiawei Shao865cad82019-04-09 08:04:59 +000052 unsigned int arrayLayers,
53 unsigned int sampleCount) {
Corentin Wallez8308b1c2017-07-03 23:02:49 -040054 switch (dimension) {
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000055 case wgpu::TextureDimension::e2D:
Jiawei Shao865cad82019-04-09 08:04:59 +000056 if (sampleCount > 1) {
57 ASSERT(arrayLayers == 1);
58 return MTLTextureType2DMultisample;
59 } else {
60 return (arrayLayers > 1) ? MTLTextureType2DArray : MTLTextureType2D;
61 }
Corentin Wallezf07e85c2019-07-15 20:47:56 +000062 default:
63 UNREACHABLE();
Corentin Wallez8308b1c2017-07-03 23:02:49 -040064 }
65 }
Jiawei Shaoe8d12b42018-10-26 06:29:38 +000066
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000067 MTLTextureType MetalTextureViewType(wgpu::TextureViewDimension dimension,
Jiawei Shao865cad82019-04-09 08:04:59 +000068 unsigned int sampleCount) {
Jiawei Shaoe8d12b42018-10-26 06:29:38 +000069 switch (dimension) {
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000070 case wgpu::TextureViewDimension::e2D:
Jiawei Shao865cad82019-04-09 08:04:59 +000071 return (sampleCount > 1) ? MTLTextureType2DMultisample : MTLTextureType2D;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000072 case wgpu::TextureViewDimension::e2DArray:
Jiawei Shaoe8d12b42018-10-26 06:29:38 +000073 return MTLTextureType2DArray;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000074 case wgpu::TextureViewDimension::Cube:
Jiawei Shao5ab84ec2018-11-16 12:11:20 +000075 return MTLTextureTypeCube;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000076 case wgpu::TextureViewDimension::CubeArray:
Jiawei Shao5ab84ec2018-11-16 12:11:20 +000077 return MTLTextureTypeCubeArray;
Jiawei Shaoe8d12b42018-10-26 06:29:38 +000078 default:
79 UNREACHABLE();
80 return MTLTextureType2D;
81 }
82 }
Jiawei Shao5dee56f2018-12-29 10:47:28 +000083
84 bool RequiresCreatingNewTextureView(const TextureBase* texture,
85 const TextureViewDescriptor* textureViewDescriptor) {
Corentin Walleza92f83b2019-06-21 10:16:15 +000086 if (texture->GetFormat().format != textureViewDescriptor->format) {
Jiawei Shao5dee56f2018-12-29 10:47:28 +000087 return true;
88 }
89
Jiawei Shao20301662019-02-21 00:45:19 +000090 if (texture->GetArrayLayers() != textureViewDescriptor->arrayLayerCount) {
Jiawei Shao5dee56f2018-12-29 10:47:28 +000091 return true;
92 }
93
Jiawei Shao20301662019-02-21 00:45:19 +000094 if (texture->GetNumMipLevels() != textureViewDescriptor->mipLevelCount) {
Jiawei Shao5dee56f2018-12-29 10:47:28 +000095 return true;
96 }
97
98 switch (textureViewDescriptor->dimension) {
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000099 case wgpu::TextureViewDimension::Cube:
100 case wgpu::TextureViewDimension::CubeArray:
Jiawei Shao5dee56f2018-12-29 10:47:28 +0000101 return true;
102 default:
103 break;
104 }
105
106 return false;
107 }
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000108
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000109 ResultOrError<wgpu::TextureFormat> GetFormatEquivalentToIOSurfaceFormat(uint32_t format) {
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000110 switch (format) {
Corentin Wallez56f3a7b2019-08-01 17:58:05 +0000111 case 'RGBA':
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000112 return wgpu::TextureFormat::RGBA8Unorm;
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000113 case 'BGRA':
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000114 return wgpu::TextureFormat::BGRA8Unorm;
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000115 case '2C08':
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000116 return wgpu::TextureFormat::RG8Unorm;
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000117 case 'L008':
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000118 return wgpu::TextureFormat::R8Unorm;
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000119 default:
120 return DAWN_VALIDATION_ERROR("Unsupported IOSurface format");
121 }
122 }
Corentin Wallezb495e482019-09-18 04:32:52 +0000123
124#if defined(DAWN_PLATFORM_MACOS)
125 MTLStorageMode kIOSurfaceStorageMode = MTLStorageModeManaged;
126#elif defined(DAWN_PLATFORM_IOS)
127 MTLStorageMode kIOSurfaceStorageMode = MTLStorageModePrivate;
128#else
129# error "Unsupported Apple platform."
130#endif
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000131 }
132
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000133 MTLPixelFormat MetalPixelFormat(wgpu::TextureFormat format) {
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000134 switch (format) {
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000135 case wgpu::TextureFormat::R8Unorm:
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000136 return MTLPixelFormatR8Unorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000137 case wgpu::TextureFormat::R8Snorm:
Corentin Wallez78430762019-07-08 09:28:51 +0000138 return MTLPixelFormatR8Snorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000139 case wgpu::TextureFormat::R8Uint:
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000140 return MTLPixelFormatR8Uint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000141 case wgpu::TextureFormat::R8Sint:
Corentin Wallez78430762019-07-08 09:28:51 +0000142 return MTLPixelFormatR8Sint;
143
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000144 case wgpu::TextureFormat::R16Uint:
Corentin Wallez78430762019-07-08 09:28:51 +0000145 return MTLPixelFormatR16Uint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000146 case wgpu::TextureFormat::R16Sint:
Corentin Wallez78430762019-07-08 09:28:51 +0000147 return MTLPixelFormatR16Sint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000148 case wgpu::TextureFormat::R16Float:
Corentin Wallez78430762019-07-08 09:28:51 +0000149 return MTLPixelFormatR16Float;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000150 case wgpu::TextureFormat::RG8Unorm:
Corentin Wallez78430762019-07-08 09:28:51 +0000151 return MTLPixelFormatRG8Unorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000152 case wgpu::TextureFormat::RG8Snorm:
Corentin Wallez78430762019-07-08 09:28:51 +0000153 return MTLPixelFormatRG8Snorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000154 case wgpu::TextureFormat::RG8Uint:
Corentin Wallez78430762019-07-08 09:28:51 +0000155 return MTLPixelFormatRG8Uint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000156 case wgpu::TextureFormat::RG8Sint:
Corentin Wallez78430762019-07-08 09:28:51 +0000157 return MTLPixelFormatRG8Sint;
158
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000159 case wgpu::TextureFormat::R32Uint:
Corentin Wallez78430762019-07-08 09:28:51 +0000160 return MTLPixelFormatR32Uint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000161 case wgpu::TextureFormat::R32Sint:
Corentin Wallez78430762019-07-08 09:28:51 +0000162 return MTLPixelFormatR32Sint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000163 case wgpu::TextureFormat::R32Float:
Corentin Wallez78430762019-07-08 09:28:51 +0000164 return MTLPixelFormatR32Float;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000165 case wgpu::TextureFormat::RG16Uint:
Corentin Wallez78430762019-07-08 09:28:51 +0000166 return MTLPixelFormatRG16Uint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000167 case wgpu::TextureFormat::RG16Sint:
Corentin Wallez78430762019-07-08 09:28:51 +0000168 return MTLPixelFormatRG16Sint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000169 case wgpu::TextureFormat::RG16Float:
Corentin Wallez78430762019-07-08 09:28:51 +0000170 return MTLPixelFormatRG16Float;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000171 case wgpu::TextureFormat::RGBA8Unorm:
Corentin Wallez78430762019-07-08 09:28:51 +0000172 return MTLPixelFormatRGBA8Unorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000173 case wgpu::TextureFormat::RGBA8UnormSrgb:
Corentin Wallez78430762019-07-08 09:28:51 +0000174 return MTLPixelFormatRGBA8Unorm_sRGB;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000175 case wgpu::TextureFormat::RGBA8Snorm:
Corentin Wallez78430762019-07-08 09:28:51 +0000176 return MTLPixelFormatRGBA8Snorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000177 case wgpu::TextureFormat::RGBA8Uint:
Corentin Wallez78430762019-07-08 09:28:51 +0000178 return MTLPixelFormatRGBA8Uint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000179 case wgpu::TextureFormat::RGBA8Sint:
Corentin Wallez78430762019-07-08 09:28:51 +0000180 return MTLPixelFormatRGBA8Sint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000181 case wgpu::TextureFormat::BGRA8Unorm:
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000182 return MTLPixelFormatBGRA8Unorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000183 case wgpu::TextureFormat::BGRA8UnormSrgb:
Corentin Wallez78430762019-07-08 09:28:51 +0000184 return MTLPixelFormatBGRA8Unorm_sRGB;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000185 case wgpu::TextureFormat::RGB10A2Unorm:
Corentin Wallez78430762019-07-08 09:28:51 +0000186 return MTLPixelFormatRGB10A2Unorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000187 case wgpu::TextureFormat::RG11B10Float:
Corentin Wallez78430762019-07-08 09:28:51 +0000188 return MTLPixelFormatRG11B10Float;
189
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000190 case wgpu::TextureFormat::RG32Uint:
Corentin Wallez78430762019-07-08 09:28:51 +0000191 return MTLPixelFormatRG32Uint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000192 case wgpu::TextureFormat::RG32Sint:
Corentin Wallez78430762019-07-08 09:28:51 +0000193 return MTLPixelFormatRG32Sint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000194 case wgpu::TextureFormat::RG32Float:
Corentin Wallez78430762019-07-08 09:28:51 +0000195 return MTLPixelFormatRG32Float;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000196 case wgpu::TextureFormat::RGBA16Uint:
Corentin Wallez78430762019-07-08 09:28:51 +0000197 return MTLPixelFormatRGBA16Uint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000198 case wgpu::TextureFormat::RGBA16Sint:
Corentin Wallez78430762019-07-08 09:28:51 +0000199 return MTLPixelFormatRGBA16Sint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000200 case wgpu::TextureFormat::RGBA16Float:
Corentin Wallez78430762019-07-08 09:28:51 +0000201 return MTLPixelFormatRGBA16Float;
202
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000203 case wgpu::TextureFormat::RGBA32Uint:
Corentin Wallez78430762019-07-08 09:28:51 +0000204 return MTLPixelFormatRGBA32Uint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000205 case wgpu::TextureFormat::RGBA32Sint:
Corentin Wallez78430762019-07-08 09:28:51 +0000206 return MTLPixelFormatRGBA32Sint;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000207 case wgpu::TextureFormat::RGBA32Float:
Corentin Wallez78430762019-07-08 09:28:51 +0000208 return MTLPixelFormatRGBA32Float;
209
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000210 case wgpu::TextureFormat::Depth32Float:
Corentin Wallez78430762019-07-08 09:28:51 +0000211 return MTLPixelFormatDepth32Float;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000212 case wgpu::TextureFormat::Depth24Plus:
Corentin Wallez78430762019-07-08 09:28:51 +0000213 return MTLPixelFormatDepth32Float;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000214 case wgpu::TextureFormat::Depth24PlusStencil8:
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000215 return MTLPixelFormatDepth32Float_Stencil8;
Corentin Wallez78430762019-07-08 09:28:51 +0000216
Corentin Wallezb629c502019-10-08 07:44:21 +0000217#if defined(DAWN_PLATFORM_MACOS)
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000218 case wgpu::TextureFormat::BC1RGBAUnorm:
Jiawei Shao55809702019-07-17 00:00:10 +0000219 return MTLPixelFormatBC1_RGBA;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000220 case wgpu::TextureFormat::BC1RGBAUnormSrgb:
Jiawei Shao55809702019-07-17 00:00:10 +0000221 return MTLPixelFormatBC1_RGBA_sRGB;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000222 case wgpu::TextureFormat::BC2RGBAUnorm:
Jiawei Shao55809702019-07-17 00:00:10 +0000223 return MTLPixelFormatBC2_RGBA;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000224 case wgpu::TextureFormat::BC2RGBAUnormSrgb:
Jiawei Shao55809702019-07-17 00:00:10 +0000225 return MTLPixelFormatBC2_RGBA_sRGB;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000226 case wgpu::TextureFormat::BC3RGBAUnorm:
Jiawei Shao55809702019-07-17 00:00:10 +0000227 return MTLPixelFormatBC3_RGBA;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000228 case wgpu::TextureFormat::BC3RGBAUnormSrgb:
Jiawei Shao55809702019-07-17 00:00:10 +0000229 return MTLPixelFormatBC3_RGBA_sRGB;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000230 case wgpu::TextureFormat::BC4RSnorm:
Jiawei Shao55809702019-07-17 00:00:10 +0000231 return MTLPixelFormatBC4_RSnorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000232 case wgpu::TextureFormat::BC4RUnorm:
Jiawei Shao55809702019-07-17 00:00:10 +0000233 return MTLPixelFormatBC4_RUnorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000234 case wgpu::TextureFormat::BC5RGSnorm:
Jiawei Shaoea2d5582019-07-10 23:58:13 +0000235 return MTLPixelFormatBC5_RGSnorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000236 case wgpu::TextureFormat::BC5RGUnorm:
Jiawei Shaoea2d5582019-07-10 23:58:13 +0000237 return MTLPixelFormatBC5_RGUnorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000238 case wgpu::TextureFormat::BC6HRGBSfloat:
Jiawei Shao55809702019-07-17 00:00:10 +0000239 return MTLPixelFormatBC6H_RGBFloat;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000240 case wgpu::TextureFormat::BC6HRGBUfloat:
Jiawei Shao55809702019-07-17 00:00:10 +0000241 return MTLPixelFormatBC6H_RGBUfloat;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000242 case wgpu::TextureFormat::BC7RGBAUnorm:
Jiawei Shao55809702019-07-17 00:00:10 +0000243 return MTLPixelFormatBC7_RGBAUnorm;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000244 case wgpu::TextureFormat::BC7RGBAUnormSrgb:
Jiawei Shao55809702019-07-17 00:00:10 +0000245 return MTLPixelFormatBC7_RGBAUnorm_sRGB;
Corentin Wallezb629c502019-10-08 07:44:21 +0000246#endif
Jiawei Shaoea2d5582019-07-10 23:58:13 +0000247
Jiawei Shaoc2750ab2019-06-01 02:30:51 +0000248 default:
249 UNREACHABLE();
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000250 }
251 }
252
253 MaybeError ValidateIOSurfaceCanBeWrapped(const DeviceBase*,
254 const TextureDescriptor* descriptor,
255 IOSurfaceRef ioSurface,
256 uint32_t plane) {
257 // IOSurfaceGetPlaneCount can return 0 for non-planar IOSurfaces but we will treat
258 // non-planar like it is a single plane.
259 size_t surfacePlaneCount = std::max(size_t(1), IOSurfaceGetPlaneCount(ioSurface));
260 if (plane >= surfacePlaneCount) {
261 return DAWN_VALIDATION_ERROR("IOSurface plane doesn't exist");
262 }
263
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000264 if (descriptor->dimension != wgpu::TextureDimension::e2D) {
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000265 return DAWN_VALIDATION_ERROR("IOSurface texture must be 2D");
266 }
267
268 if (descriptor->mipLevelCount != 1) {
269 return DAWN_VALIDATION_ERROR("IOSurface mip level count must be 1");
270 }
271
272 if (descriptor->arrayLayerCount != 1) {
273 return DAWN_VALIDATION_ERROR("IOSurface array layer count must be 1");
274 }
275
276 if (descriptor->sampleCount != 1) {
277 return DAWN_VALIDATION_ERROR("IOSurface sample count must be 1");
278 }
279
280 if (descriptor->size.width != IOSurfaceGetWidthOfPlane(ioSurface, plane) ||
281 descriptor->size.height != IOSurfaceGetHeightOfPlane(ioSurface, plane) ||
282 descriptor->size.depth != 1) {
283 return DAWN_VALIDATION_ERROR("IOSurface size doesn't match descriptor");
284 }
285
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000286 wgpu::TextureFormat ioSurfaceFormat;
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000287 DAWN_TRY_ASSIGN(ioSurfaceFormat,
288 GetFormatEquivalentToIOSurfaceFormat(IOSurfaceGetPixelFormat(ioSurface)));
289 if (descriptor->format != ioSurfaceFormat) {
290 return DAWN_VALIDATION_ERROR("IOSurface format doesn't match descriptor");
291 }
292
293 return {};
294 }
295
296 MTLTextureDescriptor* CreateMetalTextureDescriptor(const TextureDescriptor* descriptor) {
297 MTLTextureDescriptor* mtlDesc = [MTLTextureDescriptor new];
Jiawei Shao865cad82019-04-09 08:04:59 +0000298 mtlDesc.textureType = MetalTextureType(descriptor->dimension, descriptor->arrayLayerCount,
299 descriptor->sampleCount);
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000300 mtlDesc.usage = MetalTextureUsage(descriptor->usage);
301 mtlDesc.pixelFormat = MetalPixelFormat(descriptor->format);
302
303 mtlDesc.width = descriptor->size.width;
304 mtlDesc.height = descriptor->size.height;
305 mtlDesc.depth = descriptor->size.depth;
306
307 mtlDesc.mipmapLevelCount = descriptor->mipLevelCount;
308 mtlDesc.arrayLength = descriptor->arrayLayerCount;
309 mtlDesc.storageMode = MTLStorageModePrivate;
310
Jiawei Shao865cad82019-04-09 08:04:59 +0000311 mtlDesc.sampleCount = descriptor->sampleCount;
312
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000313 return mtlDesc;
Corentin Wallez0ba55502017-06-14 15:46:59 -0400314 }
315
Jiawei Shao425428f2018-08-27 08:44:48 +0800316 Texture::Texture(Device* device, const TextureDescriptor* descriptor)
Natasha Leecae68ff2019-03-27 22:04:10 +0000317 : TextureBase(device, descriptor, TextureState::OwnedInternal) {
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000318 MTLTextureDescriptor* mtlDesc = CreateMetalTextureDescriptor(descriptor);
319 mMtlTexture = [device->GetMTLDevice() newTextureWithDescriptor:mtlDesc];
320 [mtlDesc release];
Corentin Wallez0ba55502017-06-14 15:46:59 -0400321 }
322
Jiawei Shao425428f2018-08-27 08:44:48 +0800323 Texture::Texture(Device* device, const TextureDescriptor* descriptor, id<MTLTexture> mtlTexture)
Natasha Leecae68ff2019-03-27 22:04:10 +0000324 : TextureBase(device, descriptor, TextureState::OwnedInternal), mMtlTexture(mtlTexture) {
Corentin Wallezb0c75a52017-11-23 15:52:29 -0500325 [mMtlTexture retain];
Kai Ninomiya35bf4242017-07-19 15:41:17 -0700326 }
327
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000328 Texture::Texture(Device* device,
329 const TextureDescriptor* descriptor,
330 IOSurfaceRef ioSurface,
331 uint32_t plane)
Natasha Leecae68ff2019-03-27 22:04:10 +0000332 : TextureBase(device, descriptor, TextureState::OwnedInternal) {
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000333 MTLTextureDescriptor* mtlDesc = CreateMetalTextureDescriptor(descriptor);
Corentin Wallezb495e482019-09-18 04:32:52 +0000334 mtlDesc.storageMode = kIOSurfaceStorageMode;
Corentin Wallez0cdf9e02019-03-01 12:01:18 +0000335 mMtlTexture = [device->GetMTLDevice() newTextureWithDescriptor:mtlDesc
336 iosurface:ioSurface
337 plane:plane];
338 [mtlDesc release];
339 }
340
Corentin Wallez0ba55502017-06-14 15:46:59 -0400341 Texture::~Texture() {
Natasha Lee20b0c332019-04-01 19:49:04 +0000342 DestroyInternal();
Natasha Leecae68ff2019-03-27 22:04:10 +0000343 }
344
345 void Texture::DestroyImpl() {
Rafael Cintronb2b2ef52019-10-18 00:37:42 +0000346 if (GetTextureState() == TextureState::OwnedInternal) {
347 [mMtlTexture release];
348 mMtlTexture = nil;
349 }
Corentin Wallez0ba55502017-06-14 15:46:59 -0400350 }
351
352 id<MTLTexture> Texture::GetMTLTexture() {
Corentin Wallezb0c75a52017-11-23 15:52:29 -0500353 return mMtlTexture;
Corentin Wallez0ba55502017-06-14 15:46:59 -0400354 }
355
Jiawei Shaoaef480b2018-10-18 06:00:09 +0000356 TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
357 : TextureViewBase(texture, descriptor) {
Jiawei Shaoe8d12b42018-10-26 06:29:38 +0000358 id<MTLTexture> mtlTexture = ToBackend(texture)->GetMTLTexture();
Jiawei Shao5dee56f2018-12-29 10:47:28 +0000359
360 if (!UsageNeedsTextureView(texture->GetUsage())) {
361 mMtlTextureView = nil;
362 } else if (!RequiresCreatingNewTextureView(texture, descriptor)) {
363 mMtlTextureView = [mtlTexture retain];
364 } else {
365 MTLPixelFormat format = MetalPixelFormat(descriptor->format);
Jiawei Shao865cad82019-04-09 08:04:59 +0000366 MTLTextureType textureViewType =
367 MetalTextureViewType(descriptor->dimension, texture->GetSampleCount());
Jiawei Shao20301662019-02-21 00:45:19 +0000368 auto mipLevelRange = NSMakeRange(descriptor->baseMipLevel, descriptor->mipLevelCount);
369 auto arrayLayerRange =
370 NSMakeRange(descriptor->baseArrayLayer, descriptor->arrayLayerCount);
Jiawei Shao5dee56f2018-12-29 10:47:28 +0000371
372 mMtlTextureView = [mtlTexture newTextureViewWithPixelFormat:format
373 textureType:textureViewType
374 levels:mipLevelRange
375 slices:arrayLayerRange];
376 }
Corentin Wallez0ba55502017-06-14 15:46:59 -0400377 }
Corentin Wallezf58d84d2017-11-24 14:12:44 -0500378
Jiawei Shaoe8d12b42018-10-26 06:29:38 +0000379 TextureView::~TextureView() {
380 [mMtlTextureView release];
381 }
382
383 id<MTLTexture> TextureView::GetMTLTexture() {
Jiawei Shao5dee56f2018-12-29 10:47:28 +0000384 ASSERT(mMtlTextureView != nil);
Jiawei Shaoe8d12b42018-10-26 06:29:38 +0000385 return mMtlTextureView;
386 }
Corentin Wallez49a65d02018-07-24 16:45:45 +0200387}} // namespace dawn_native::metal