Объекты ресурса: буферы и текстуры
В этой главе описываются Металлические объекты ресурса (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-разрядные компоненты цвета. Каждый компонент располагается в увеличении адресов памяти с первым перечисленным компонентом в самом низком адресе. Например,
MTLPixelFormatRGBA8Unorm32-разрядный формат с восемью битами для каждого компонента цвета; самые низкие адреса содержат красный, следующие адреса содержат зеленый и т.д. Напротив, дляMTLPixelFormatBGRA8Unorm, самые низкие адреса содержат синий, следующие адреса содержат зеленый и т.д.Упакованные форматы комбинируют многократные компоненты в одно 16-разрядное или 32-разрядное значение, где компоненты сохранены от наименьшего количества до старшего значащего бита (LSB к MSB). Например,
MTLPixelFormatRGB10A2Uint32-разрядный упакованный формат, состоящий из трех 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).