Объекты ресурса: буферы и текстуры
В этой главе описываются Металлические объекты ресурса (MTLResource
) для хранения бесформатной памяти и отформатированных данных изображения. Существует два типа MTLResource
объекты:
MTLBuffer
представляет выделение бесформатной памяти, которая может содержать любой тип данных. Буферы часто используются для вершины, программы построения теней, и вычисляют данные состояния.MTLTexture
представляет выделение отформатированных данных изображения с указанным типом текстуры и форматом пикселя. Объекты текстуры используются в качестве исходных текстур для вершины, фрагмента, или вычисляют функции, а также сохранить вывод рендеринга графики (т.е. как присоединение).
MTLSamplerState
объекты также обсуждены в этой главе. Несмотря на то, что сэмплеры не являются самими ресурсами, они используются при выполнении вычислений поиска с объектом текстуры.
Буферы являются выделениями без типов памяти
A MTLBuffer
объект представляет выделение памяти, которая может содержать любой тип данных.
Создание буферного объекта
Следующий MTLDevice
методы создают и возвращают a MTLBuffer
объект:
newBufferWithLength:options:
метод создает aMTLBuffer
объект с новым выделением ресурсов хранения.newBufferWithBytes:length:options:
метод создает aMTLBuffer
объект путем копирования данных с существующего хранения (расположенный в адресе CPUpointer
) в новое выделение ресурсов хранения.newBufferWithBytesNoCopy:length:options:deallocator:
метод создает aMTLBuffer
объект с существующим выделением ресурсов хранения и не выделяет нового хранения для этого объекта.
Все буферные методы создания имеют входное значение length
указать размер выделения ресурсов хранения, в байтах. Все методы также принимают a MTLResourceOptions
объект для options
это может изменить поведение создаваемого буфера. Если значение для options
0, значения по умолчанию используются для опций ресурса.
Буферные методы
MTLBuffer
протокол имеет следующие методы:
contents
метод возвращает адрес CPU выделения ресурсов хранения буфера.newTextureWithDescriptor:offset:bytesPerRow:
метод создает специальный вид объекта текстуры, ссылающегося на данные буфера. Этот метод детализирован в Создании Объекта Текстуры.
Текстуры являются отформатированными данными изображения
A MTLTexture
объект представляет выделение отформатированных данных изображения, которые могут использоваться в качестве ресурса для вершинного шейдера, программы построения теней фрагмента, или вычислить функцию, или как присоединение, которое будет использоваться в качестве места назначения рендеринга. A MTLTexture
объект может иметь одну из следующих структур:
1D, 2D, или 3D изображение
Массив 1D или 2D изображения
Куб шести 2D изображений
MTLPixelFormat
указывает организацию отдельных пикселей в a MTLTexture
объект. Форматы пикселя обсуждены далее в Форматах пикселя для Текстур.
Создание объекта текстуры
Следующие методы создают и возвращают a MTLTexture
объект:
newTextureWithDescriptor:
методMTLDevice
создает aMTLTexture
объект с новым выделением ресурсов хранения для данных изображения текстуры, с помощью aMTLTextureDescriptor
объект описать свойства текстуры.newTextureViewWithPixelFormat:
методMTLTexture
создает aMTLTexture
возразите, что совместно использует то же выделение ресурсов хранения как вызовMTLTexture
объект. Так как они совместно используют то же хранение, любые изменения в пикселях нового объекта текстуры отражаются в объекте текстуры вызова, и наоборот. Для недавно создаваемой текстуры,newTextureViewWithPixelFormat:
метод дает иное толкование существующим данным изображения текстуры выделения ресурсов хранения вызоваMTLTexture
возразите, как будто данные хранились в указанном формате пикселя.MTLPixelFormat
из новой текстуры объект должен быть совместим сMTLPixelFormat
из исходного объекта текстуры. (См. Форматы пикселя для Текстур для подробных данных об обычных, упакованных, и сжатых форматах пикселя.)newTextureWithDescriptor:offset:bytesPerRow:
методMTLBuffer
создает aMTLTexture
возразите, что совместно использует выделение ресурсов хранения вызоваMTLBuffer
возразите как его данные изображения текстуры. Поскольку они совместно используют то же хранение, любые изменения в пикселях нового объекта текстуры отражаются в объекте текстуры вызова, и наоборот. Совместное использование хранения между текстурой и буфером может предотвратить использование определенной оптимизации текстурирования, такой как пиксель swizzling или мозаичное размещение.
Создание объекта текстуры с дескриптором текстуры
MTLTextureDescriptor
определяет свойства, использующиеся для создания a MTLTexture
объект, включая его размер изображения (ширина, высота и глубина), формат пикселя, расположение (тип массива или тип куба) и число множественных отображений. MTLTextureDescriptor
свойства только используются во время создания a MTLTexture
объект. После создания a MTLTexture
объект, свойство изменяется в MTLTextureDescriptor
объект больше не имеет эффекта на ту текстуру.
Создать одну или более текстур из дескриптора:
Создайте пользовательское
MTLTextureDescriptor
объект, содержащий свойства текстуры, описывающие данные текстуры:textureType
свойство указывает размерность и расположение текстуры (например, массив или куб).width
,height
, иdepth
свойства указывают, что множественно отображается размер пикселя в каждой размерности основной текстуры уровня.pixelFormat
свойство указывает, как пиксель сохранен в текстуре.arrayLength
свойство указывает число элементов матрицы для aMTLTextureType1DArray
илиMTLTextureType2DArray
введите объект текстуры.mipmapLevelCount
свойство указывает число уровней множественного отображения.sampleCount
свойство указывает число выборок в каждом пикселе.resourceOptions
свойство указывает поведение своего выделения памяти.
Создайте текстуру из
MTLTextureDescriptor
объект путем вызоваnewTextureWithDescriptor:
метод aMTLDevice
объект. После создания текстуры вызовитеreplaceRegion:mipmapLevel:slice:withBytes:bytesPerRow:bytesPerImage:
метод для загрузки данных изображения текстуры, как детализировано в Копировании Данных изображения к и от Текстуры.Создать больше
MTLTexture
объекты, можно снова использовать то жеMTLTextureDescriptor
объект, изменяя значения свойств дескриптора по мере необходимости.
Перечисление 3-1 показывает код для создания дескриптора текстуры txDesc
и установка ее свойств для 3D, 64x64x64 текстура.
Перечисление 3-1 , создающее объект текстуры с пользовательским дескриптором текстуры
MTLTextureDescriptor* txDesc = [MTLTextureDescriptor new]; |
txDesc.textureType = MTLTextureType3D; |
txDesc.height = 64; |
txDesc.width = 64; |
txDesc.depth = 64; |
txDesc.pixelFormat = MTLPixelFormatBGRA8Unorm; |
txDesc.arrayLength = 1; |
txDesc.mipmapLevelCount = 1; |
id <MTLTexture> aTexture = [device newTextureWithDescriptor:txDesc]; |
Работа с частями текстуры
Часть является синглом 1D, 2D, или 3D изображение текстуры и все его связанные множественные отображения. Для каждой части:
Размер основного множественного отображения уровня указан
width
,height
, иdepth
свойстваMTLTextureDescriptor
объект.Масштабированный размер уровня множественного отображения я указан макс. (1, пол (
width
/ 2i)) x макс. (1, пол (height
/ 2i)) x макс. (1, пол (depth
/ 2i)). Максимальный уровень множественного отображения является первым уровнем множественного отображения, где достигается размер 1 x 1 x 1.Число уровней множественного отображения в одной части может быть определено полом (log2 (макс. (
width
,height
,depth
))) +1.
Все объекты текстуры имеют по крайней мере одну часть; куб и типы текстуры массива могут иметь несколько частей. В методах, пишущих и читающих данные изображения текстуры, обсужденные в Копировании Данных изображения к и от Текстуры, slice
основанное на нуле входное значение. Для 1D, 2D, или 3D текстура, существует только одна часть, таким образом, значение slice
должен быть 0. Кубическая текстура имеет шесть общих 2D частей, адресуемых от 0 до 5. Для 1DArray и 2DArray типы текстуры, каждый элемент матрицы представляет одну часть. Например, для 2DArray текстурируют тип с arrayLength
= 10, существует 10 общих частей, адресуемых от 0 до 9. Для выбора сингла 1D, 2D, или 3D изображение из полной структуры текстуры, сначала выбирают часть, и затем выбирают уровень множественного отображения в той части.
Создание дескриптора текстуры с удобными методами
Для общих 2D и кубических текстур используйте следующие удобные методы создать a MTLTextureDescriptor
объект с несколькими из его значений свойств автоматически установил:
texture2DDescriptorWithPixelFormat:width:height:mipmapped:
метод создает aMTLTextureDescriptor
объект для 2D текстуры.width
иheight
значения определяют размерности 2D текстуры.type
свойство автоматически установлено вMTLTextureType2D
, иdepth
иarrayLength
установлены в 1.textureCubeDescriptorWithPixelFormat:size:mipmapped:
метод создает aMTLTextureDescriptor
объект для кубической текстуры, гдеtype
свойство установлено вMTLTextureTypeCube
,width
иheight
установлены измерить, иdepth
иarrayLength
установлены в 1.
Оба MTLTextureDescriptor
удобные методы принимают входное значение, pixelFormat
, который определяет формат пикселя текстуры. Оба метода также принимают входное значение mipmapped
, который определяет, множественно отображается ли изображение текстуры. (Если mipmapped
YES
, текстура множественно отображается.)
Перечисление 3-2 использует texture2DDescriptorWithPixelFormat:width:height:mipmapped:
метод для создания дескриптора возражает для a 64x64
Не множественно отображающаяся 2D текстура.
Перечисление 3-2 , создающее объект текстуры с дескриптором текстуры удобства
MTLTextureDescriptor *texDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm width:64 height:64 mipmapped:NO]; id <MTLTexture> myTexture = [device newTextureWithDescriptor:texDesc]; |
Копирование данных изображения к и от текстуры
Синхронно скопировать данные изображения в или данные копии от выделения ресурсов хранения a MTLTexture
объект, используйте следующие методы:
replaceRegion:mipmapLevel:slice:withBytes:bytesPerRow:bytesPerImage:
копирует область пиксельных данных от указателя вызывающей стороны в часть выделения ресурсов хранения указанной части текстуры.replaceRegion:mipmapLevel:withBytes:bytesPerRow:
подобный удобный метод, копирующий область пиксельных данных в часть по умолчанию, принимая значения по умолчанию для связанных с частью параметров (т.е.slice
= 0 иbytesPerImage
= 0).getBytes:bytesPerRow:bytesPerImage:fromRegion:mipmapLevel:slice:
получает область пиксельных данных от указанной части текстуры.getBytes:bytesPerRow:fromRegion:mipmapLevel:
подобный удобный метод, получающий область пиксельных данных от части по умолчанию, принимая значения по умолчанию для связанных с частью параметров (slice
= 0 иbytesPerImage
= 0).
Перечисление 3-3 показывает, как вызвать replaceRegion:mipmapLevel:slice:withBytes:bytesPerRow:bytesPerImage:
для указания текстуры отображают от исходных данных в системной памяти, textureData
, в части 0
и множественно отобразите уровень 0
.
Перечисление 3-3 , копирующее данные изображения в текстуру
// pixelSize is the size of one pixel, in bytes |
// width, height - number of pixels in each dimension |
NSUInteger myRowBytes = width * pixelSize; |
NSUInteger myImageBytes = rowBytes * height; |
[tex replaceRegion:MTLRegionMake2D(0,0,width,height) |
mipmapLevel:0 slice:0 withBytes:textureData |
bytesPerRow:myRowBytes bytesPerImage:myImageBytes]; |
Форматы пикселя для текстур
MTLPixelFormat
указывает организацию цвета, глубины и хранения данных шаблона в отдельных пикселях a MTLTexture
объект. Существует три варианта форматов пикселя: обычный, упакованный и сжатый.
Обычные форматы имеют только регулярные 8-, 16-, или 32-разрядные компоненты цвета. Каждый компонент располагается в увеличении адресов памяти с первым перечисленным компонентом в самом низком адресе. Например,
MTLPixelFormatRGBA8Unorm
32-разрядный формат с восемью битами для каждого компонента цвета; самые низкие адреса содержат красный, следующие адреса содержат зеленый и т.д. Напротив, дляMTLPixelFormatBGRA8Unorm
, самые низкие адреса содержат синий, следующие адреса содержат зеленый и т.д.Упакованные форматы комбинируют многократные компоненты в одно 16-разрядное или 32-разрядное значение, где компоненты сохранены от наименьшего количества до старшего значащего бита (LSB к MSB). Например,
MTLPixelFormatRGB10A2Uint
32-разрядный упакованный формат, состоящий из трех 10-разрядных каналов (для R, G, и B) и два бита для альфы.Сжатые форматы располагаются в блоках пикселей, и расположение каждого блока является определенным для того формата пикселя. Сжатые форматы пикселя могут только использоваться для 2D, 2D Массива или типов кубической текстуры. Сжатые форматы не могут использоваться для создания 1D, 2DMultisample или 3D текстуры.
MTLPixelFormatGBGR422
и MTLPixelFormatBGRG422
специальные форматы пикселя, предназначающиеся для хранения пикселей в цветовом пространстве YUV. Эти форматы только поддерживаются для 2D текстур (но ни 2D Массив, ни тип куба), без множественных отображений, и даже width
.
Несколько форматов пикселя хранят компоненты цвета sRGB значениями цветового пространства (например, MTLPixelFormatRGBA8Unorm_sRGB
или MTLPixelFormatETC2_RGB8_sRGB
). Когда работа выборки ссылается на текстуру с sRGB форматом пикселя, Металлическая реализация преобразовывает sRGB компоненты цветового пространства в линейное цветовое пространство, прежде чем работа выборки будет иметь место. Преобразование из sRGB компонента, S, к линейному компоненту, L, следующие:
Если S <= 0.04045, L = S/12.92
Если S> 0.04045, L = ((S+0.055)/1.055) 2.4
С другой стороны, при рендеринге к цветному-renderable присоединению, использующему текстуру с sRGB форматом пикселя, реализация преобразовывает линейные значения цвета в sRGB, следующим образом:
Если L <= 0.0031308, S = L * 12.92
Если L> 0.0031308, S = (1.055 * L0.41667) - 0.055
Для получения дополнительной информации о формате пикселя для рендеринга, посмотрите Создание Дескриптора Передачи Рендеринга.
Создание объекта состояний сэмплера для поиска текстуры
A MTLSamplerState
объект определяет обращение, фильтрация и другие свойства, использующиеся, когда графика или вычисляют функцию, выполняют операции выборки текстуры на a MTLTexture
объект. Дескриптор сэмплера определяет свойства объекта состояния сэмплера. Создать объект состояния сэмплера:
Вызовите
newSamplerStateWithDescriptor:
метод aMTLDevice
объект создать aMTLSamplerDescriptor
объект.Установите требуемые значения в
MTLSamplerDescriptor
объект, включая фильтрацию опций, способов адресации, максимальной анизотропии и параметров уровня детализации.Создайте a
MTLSamplerState
объект от дескриптора сэмплера путем вызоваnewSamplerStateWithDescriptor:
методMTLDevice
возразите, что создал дескриптор.
Можно снова использовать объект дескриптора сэмплера создать больше MTLSamplerState
объекты, изменяя значения свойств дескриптора по мере необходимости. Свойства дескриптора только используются во время создания объекта. После того, как состояние сэмплера было создано, изменение свойств в его дескрипторе больше не имеет эффект на то состояние сэмплера.
Перечисление 3-4 является примером кода, создающим a MTLSamplerDescriptor
и конфигурирует его для создания a MTLSamplerState
. Значения не по умолчанию установлены для фильтра и свойств режима адреса объекта дескриптора. Тогда newSamplerStateWithDescriptor:
метод использует дескриптор сэмплера для создания объекта состояния сэмплера.
Перечисление 3-4 , создающее объект состояния сэмплера
// create MTLSamplerDescriptor |
MTLSamplerDescriptor *desc = [[MTLSamplerDescriptor alloc] init]; |
desc.minFilter = MTLSamplerMinMagFilterLinear; |
desc.magFilter = MTLSamplerMinMagFilterLinear; |
desc.sAddressMode = MTLSamplerAddressModeRepeat; |
desc.tAddressMode = MTLSamplerAddressModeRepeat; |
// all properties below have default values |
desc.mipFilter = MTLSamplerMipFilterNotMipmapped; |
desc.maxAnisotropy = 1U; |
desc.normalizedCoords = YES; |
desc.lodMinClamp = 0.0f; |
desc.lodMaxClamp = FLT_MAX; |
// create MTLSamplerState |
id <MTLSamplerState> sampler = [device newSamplerStateWithDescriptor:desc]; |
Поддержание когерентности между CPU и памятью GPU
И CPU и GPU могут получить доступ к базовой системе хранения для a MTLResource
объект. Однако GPU управляет асинхронно от узла CPU, поэтому помните следующее при использовании узла CPU для доступа к хранению для этих ресурсов.
При выполнении a MTLCommandBuffer
объект, MTLDevice
объект, как только гарантируют, будет наблюдать любые изменения, внесенные узлом CPU к выделению ресурсов хранения любого MTLResource
на объект ссылается это MTLCommandBuffer
возразите, были ли (и только если) те изменения внесены узлом CPU перед MTLCommandBuffer
объект фиксировался. Т.е. MTLDevice
объект не мог бы наблюдать изменения в ресурсе, который узел CPU делает после соответствия MTLCommandBuffer
объект фиксировался (т.е. status
свойство MTLCommandBuffer
объект MTLCommandBufferStatusCommitted
).
Точно так же после MTLDevice
объект выполняет a MTLCommandBuffer
объект, узел CPU, как только гарантируют, будет наблюдать любые изменения MTLDevice
объект делает к выделению ресурсов хранения любого ресурса ссылаемый тем буфером команд, если буфер команд завершил выполнение (т.е. status
свойство MTLCommandBuffer
объект MTLCommandBufferStatusCompleted
).