GPUDevice: метод createRenderPipeline()
Ограниченная доступность
Эта функция не относится к Baseline, так как она не работает во всех широко используемых браузерах.
Экспериментально: Это экспериментальная технология
Внимательно проверьте таблицу совместимости с браузерами перед использованием в продакшене.
Безопасный контекст: Эта функция доступна только в безопасных контекстах (HTTPS) в некоторых или всех поддерживающих браузерах.
Примечание: Эта функция доступна в Web Workers.
Метод createRenderPipeline() интерфейса GPUDevice создаёт GPURenderPipeline, который может управлять этапами вершинного и фрагментного шейдеров и использоваться в GPURenderPassEncoder или GPURenderBundleEncoder.
Синтаксис
createRenderPipeline(descriptor)
Параметры
descriptor-
Объект, содержащий следующие свойства:
depthStencilНеобязательно-
Объект (см.
depthStencilструктуру объекта) описывающий свойства глубины и трафарета, включая проверку, операции и смещение. fragmentНеобязательно-
Объект (см.
fragmentструктуру объекта) описывающий точку входа фрагментного шейдера в конвейер и его выходные цвета. Если точка входа фрагментного шейдера не определена, конвейер не будет генерировать выходные цвета для прикреплений, но всё равно будет выполнять растрирование и генерировать значения глубины, основанные на выходных вершинных координатах. Проверка глубины и операции с трафаретом по-прежнему могут быть использованы. labelНеобязательно-
Строка, предоставляющая метку, которая может использоваться для идентификации объекта, например, в сообщениях
GPUErrorили предупреждениях консоли. layout-
Определяет макет (структура, назначение и тип) всех ресурсов GPU (буферы, текстуры и т. д.), используемых во время выполнения конвейера. Возможные значения:
- Объект
GPUPipelineLayout, созданный с помощьюGPUDevice.createPipelineLayout(), который позволяет GPU определить, как запустить конвейер наиболее эффективно заранее. - Строка
"auto", которая заставляет конвейер генерировать неявной макет группы привязок на основе любых привязок, определённых в коде шейдера. Если используется"auto", сгенерированные макеты групп привязок могут использоваться только с текущим конвейером.
- Объект
multisampleНеобязательно-
Объект (см.
multisampleструктуру объекта) описывающий взаимодействие конвейера с многообразными прикреплениями прохода рендеринга. primitiveНеобязательно-
Объект (см.
primitiveструктуру объекта) описывающий, как конвейер строит и растрирует примитивы из его вершинных входов. vertex-
Объект (см.
vertexструктуру объекта) описывающий точку входа вершинного шейдера в конвейер и макеты входных буферов.
depthStencil структура объекта
Объект depthStencil может содержать следующие свойства:
depthBiasНеобязательно-
Число, представляющее постоянную смещение глубины, добавляемую к каждому фрагменту. Если опущено,
depthBiasпо умолчанию равно 0.Примечание: Свойства
depthBias,depthBiasClamp, иdepthBiasSlopeScaleдолжны быть установлены в0для топологий линий и точек, т.е. еслиtopologyустановлено в"line-list","line-strip", или"point-list". В противном случае будет сгенерирована ошибкаGPUValidationError, и возвращаемаяGPURenderPipelineбудет недействительной. depthBiasClampНеобязательно-
Число, представляющее максимальное смещение глубины фрагмента. Если опущено,
depthBiasClampпо умолчанию равно 0. depthBiasSlopeScaleНеобязательно-
Число, представляющее смещение глубины, масштабируемое с наклоном фрагмента. Если опущено,
depthBiasSlopeScaleпо умолчанию равно 0. depthCompareНеобязательно-
Перечисление, определяющее операцию сравнения, используемую для проверки глубины фрагментов по отношению к
depthStencilAttachmentзначениям глубины. Возможные значения:-
"never": Тесты сравнения никогда не проходят. -
"less": Предоставленное значение проходит тест сравнения, если оно меньше значения выборки. -
"equal": Предоставленное значение проходит тест сравнения, если оно равно значению выборки. -
"less-equal": Предоставленное значение проходит тест сравнения, если оно меньше или равно значению выборки. -
"greater": Предоставленное значение проходит тест сравнения, если оно больше значения выборки. -
"not-equal": Предоставленное значение проходит тест сравнения, если оно не равно значению выборки. -
"greater-equal": Предоставленное значение проходит тест сравнения, если оно больше или равно значению выборки. -
"always": Тесты сравнения всегда проходят.
depthCompareне требуется, если указанныйformatне имеет компонента глубины или если операция сравнения не используется. -
depthWriteEnabledНеобязательно-
Булево значение. Значение
trueуказывает, чтоGPURenderPipelineможет изменятьdepthStencilAttachmentзначения глубины после создания. Установка вfalseозначает, что это невозможно.depthWriteEnabledне требуется, если указанныйformatне имеет компонента глубины. format-
Перечисление, определяющее формат
depthStencilAttachmentс которым будет совместимGPURenderPipeline. Смотрите раздел Форматы текстур в спецификации для всех доступных значенийformat. stencilBackНеобязательно-
Объект, определяющий, как выполняются сравнения и операции с маскировкой глубины для обращенных назад примитивов. Его свойства могут включать:
compareНеобязательно-
Перечисление, определяющее операцию сравнения, используемую при проверке фрагментов относительно
depthStencilAttachmentзначений маскировки глубины. Возможные значения такие же, как для свойстваdepthCompare; см. выше. Если опущено,compareпо умолчанию равно"always". depthFailOpНеобязательно-
Перечисление, определяющее операцию маскировки глубины, выполняемую, если сравнение фрагмента по глубине, описанное
depthCompare, завершится неудачно. Возможные значения:-
"decrement-clamp": Уменьшить текущее значение маскировки глубины, ограничив его 0. -
"decrement-wrap": Уменьшить текущее значение маскировки глубины, переходя к максимальному представимому значению аспекта маскировки глубины, если значение станет меньше 0. -
"invert": Побитовое отрицание текущего значения маскировки глубины. -
"increment-clamp": Увеличить текущее значение маскировки глубины, ограничив его максимальным представимым значением аспекта маскировки глубины. -
"increment-wrap": Увеличить текущее значение маскировки глубины, переходя к нулю, если значение превысит максимальное представимое значение аспекта маскировки глубины. -
"keep": Сохранить текущее значение. -
"replace": Установить значение маскировки глубины на текущее значение. -
"zero": Установить значение маскировки глубины в 0.
Если опущено,
depthFailOpпо умолчанию равно"keep".Примечание: Значение маскировки глубины в состоянии рендеринга инициализируется значением 0 в начале прохода рендеринга.
-
failOpНеобязательно-
Перечисление, определяющее операцию маскировки глубины, выполняемую, если тест сравнения фрагмента с маскировкой глубины, описанный
compare, завершится неудачно. Возможные и значения по умолчанию такие же, как дляdepthFailOp. passOpНеобязательно-
Перечисление, определяющее операцию маскировки глубины, выполняемую, если тест сравнения фрагмента с маскировкой глубины, описанный
compare, завершится успешно. Возможные и значения по умолчанию такие же, как дляdepthFailOp.
stencilFrontНеобязательно-
Объект, определяющий, как выполняются сравнения и операции с маскировкой глубины для направленных вперед примитивов. Его свойства такие же, как для
stencilBack. stencilReadMaskНеобязательно-
Маска битов, управляющая тем, какие биты
depthStencilAttachmentзначения маскировки глубины считываются при выполнении тестов сравнения маскировки глубины. Если опущено,stencilReadMaskпо умолчанию равно0xFFFFFFFF. stencilWriteMaskНеобязательно-
Маска битов, управляющая тем, какие биты
depthStencilAttachmentзначения маскировки глубины записываются при выполнении операций с маскировкой глубины. Если опущено,stencilWriteMaskпо умолчанию равно0xFFFFFFFF.
Примечание: Значения depthStencilAttachment задаются во время вызовов GPUCommandEncoder.beginRenderPass(), когда GPURenderPipeline фактически используется для выполнения прохода рендеринга.
fragment структура объекта
Объект fragment содержит массив объектов, каждый из которых может содержать следующие свойства:
constantsНеобязательно-
Последовательность типов записей со структурой
(id, value), представляющая значения переопределения для констант WGSL, которые могут быть переопределены в конвейере. Они ведут себя как упорядоченные карты. В каждом случаеidявляется ключом для идентификации или выбора записи, аconstant— перечисление, представляющее значение WGSL.В зависимости от константы, которую вы хотите переопределить,
idможет принимать вид числового идентификатора константы, если он указан, или иначе — идентификатора имени константы.Пример кода, предоставляющий значения переопределения для нескольких переопределяемых констант, может выглядеть так:
{ // ... constants: { 0: false, 1200: 3.0, 1300: 2.0, width: 20, depth: -1, height: 15, } } entryPointНеобязательно-
Имя функции в
module, которую этот этап будет использовать для выполнения своей работы. Соответствующая функция шейдера должна иметь атрибут@fragment, чтобы быть идентифицированной как эта точка входа. Подробнее см. Описание точки входа.Вы можете опустить свойство
entryPoint, если ваш код шейдера содержит единственную функцию с заданным атрибутом@fragment— браузер будет использовать её в качестве точки входа по умолчанию. ЕслиentryPointопущено и браузер не может определить точку входа по умолчанию, генерируетсяGPUValidationError, и полученнаяGPURenderPipelineбудет недействительной. module-
Объект
GPUShaderModule, содержащий код WGSL, который будет выполняться этим программируемым этапом. targets-
Массив объектов, представляющих состояния цвета, которые описывают параметры конфигурации цветов, выводимых этапом фрагментного шейдера. Эти объекты могут включать следующие свойства:
blendНеобязательно-
Объект, описывающий режим смешивания, применяемый к выводимому цвету.
blendимеет два свойства:alphaиcolorоба принимают объект в качестве значения, который может включать следующие свойства:dstFactorНеобязательно-
Перечисление, определяющее операцию смешивания, выполняемую над значениями из целевого прикрепления. Возможные значения:
"constant""dst""dst-alpha""one""one-minus-dst""one-minus-src""one-minus-src1""one-minus-src-alpha""one-minus-src1-alpha""one-minus-dst-alpha""one-minus-constant""src""src1""src-alpha""src1-alpha""src-alpha-saturated""zero"
Если опущено,
dstFactorпо умолчанию равно"zero".Примечание: Для успешного использования операций смешивания
dual-source-blendingфункция должна быть включена. В противном случае генерируетсяGPUValidationError. operationНеобязательно-
Перечисление, определяющее алгоритм объединения исходных и целевых коэффициентов смешивания для расчета конечных значений, записываемых в компоненты целевого прикрепления. Возможные значения:
"add""max""min""reverse-subtract""subtract"
Если опущено,
operationпо умолчанию равно"add". srcFactorНеобязательно-
Перечисление, определяющее операцию смешивания, выполняемую над значениями из фрагментного шейдера. Возможные значения такие же, как и для
dstFactor. Если опущено,srcFactorпо умолчанию равно"one".
Примечание: Для подробного объяснения алгоритмов, определённых каждым перечислением
dstFactor/srcFactorиoperation, см. раздел Состояние смешивания спецификации. format-
Перечисление, определяющее требуемый формат выходных цветов. Все доступные значения
formatсм. в разделе Форматы текстур спецификации. writeMaskНеобязательно-
Один или несколько битовых флагов, определяющих маску записи, применяемую к состоянию целевого цвета. Возможные значения флагов:
GPUColorWrite.REDGPUColorWrite.GREENGPUColorWrite.BLUEGPUColorWrite.ALPHAGPUColorWrite.ALL
Если опущено,
writeMaskпо умолчанию равноGPUColorWrite.ALL.Обратите внимание, что несколько флагов можно указать, разделяя значения символом |, например:
writeMask: GPUColorWrite.RED | GPUColorWrite.ALPHA;
multisample структура объекта
Объект multisample может содержать следующие свойства:
alphaToCoverageEnabledНеобязательно-
Булево значение. Значение
trueуказывает, что альфа-канал фрагмента должен использоваться для генерации маски охвата выборки. Если опущено,alphaToCoverageEnabledпо умолчанию равноfalse. countНеобязательно-
Число, определяющее количество выборок на пиксель. Конвейер будет совместим только с текстурами прикрепления (
colorAttachmentиdepthStencilAttachment), с соответствующимsampleCounts(см.GPUTexture).Если опущено,
countпо умолчанию равно 1. maskНеобязательно-
Битовая маска, определяющая, какие выборки записываются. Если опущено,
maskпо умолчанию равно0xFFFFFFFF.
Примечание: Значения colorAttachment и depthStencilAttachment задаются во время вызовов GPUCommandEncoder.beginRenderPass(), когда GPURenderPipeline фактически используется для выполнения прохода рендеринга.
primitive структура объекта
Объект primitive может содержать следующие свойства:
cullModeНеобязательно-
Перечисление, определяющее, какая ориентация полигонов будет отсекаться (если таковая есть). Возможные значения:
-
"back": Отсекаются заднесторонние полигоны. -
"front": Отсекаются переднесторонние полигоны. -
"none": Никакие полигоны не отсекаются.
Если опущено,
cullModeпо умолчанию равно"none". -
frontFaceНеобязательно-
Перечисление, определяющее, какие полигоны считаются переднесторонними. Возможные значения:
-
"ccw": Полигоны с вершинами, координаты которых в буфере фреймов заданы в порядке против часовой стрелки. -
"cw": Полигоны с вершинами, координаты которых в буфере фреймов заданы в порядке по часовой стрелке.
Если опущено,
frontFaceпо умолчанию равно"ccw".Примечание:>
frontFaceиcullModeне оказывают влияния на топологии"point-list","line-list"или"line-strip". -
stripIndexFormatНеобязательно-
Перечисление, определяющее формат буфера индексов и значение для перезапуска примитивов в случае конвейеров с топологией полосок (
"line-strip"или0xFFFF). Значение перезапуска примитива указывает, какое значение индекса обозначает начало нового примитива, а не продолжение построения полоски с предыдущими индексированными вершинами. Возможные значения:-
"uint16": Указывает размер в байтах 2 и значение для перезапуска примитива0xFFFF. -
"uint32": Указывает размер в байтах 4 и значение для перезапуска примитива0xFFFFFFFF.
Состояния примитивов GPU, которые указывают топологию примитива полоски, должны указать формат индекса полоски, если они используются для индексированных отрисовок (например, с помощью
GPURenderPassEncoder.drawIndexed()), чтобы значение для перезапуска примитива было известно во время создания конвейера. Конвейеры с топологиями примитивов списка ("line-list","point-list", или"triangle-list") не должны указывать значениеstripIndexFormat. Вместо этого они будут использовать формат индексов, переданный, например,GPURenderPassEncoder.setIndexBuffer(), при индексированном рендеринге. -
topologyНеобязательно-
Перечисление, определяющее тип примитива, который будет построен из указанных
vertexвходных данных. Возможные значения:-
"line-list": Каждая последующая пара из двух вершин определяет примитив линии. -
"line-strip": Каждая вершина после первой определяет примитив линии между ней и предыдущей вершиной. -
"triangle-list": Каждая вершина определяет примитив точки. -
"triangle-strip": Каждая последующая тройка из трёх вершин определяет примитив треугольника. -
"triangle-strip": Каждая вершина после первых двух определяет примитив треугольника между ней и двумя предыдущими вершинами.
Если опущено,
topologyпо умолчанию равно"triangle-list". -
unclippedDepthНеобязательно-
Булево значение. Значение
trueуказывает, что отсечение по глубине отключено. Если опущено,unclippedDepthпо умолчанию равноfalse. Обратите внимание, что для управления отсечением по глубине необходимо включитьdepth-clip-controlфункцию вGPUDevice.Примечание: Для успешного использования свойства
unclippedDepthнеобходимо включитьdepth-clip-controlфункцию. В противном случае генерируетсяGPUValidationError.
vertex структура объекта
Объект vertex может содержать следующие свойства:
constantsНеобязательно-
Последовательность типов записей со структурой
(id, value), представляющих значения переопределения для констант WGSL, которые можно переопределить в конвейере. Они ведут себя как упорядоченные отображения. В каждом случаеid— ключ, используемый для идентификации или выбора записи, аconstant— перечисленное значение, представляющее WGSL.В зависимости от константы, которую вы хотите переопределить,
idможет принимать форму числового идентификатора константы, если он указан, или иначе имя идентификатора константы.Пример кода, предоставляющий значения переопределения для нескольких переопределяемых констант, может выглядеть так:
{ // ... constants: { 0: false, 1200: 3.0, 1300: 2.0, width: 20, depth: -1, height: 15, } } entryPointНеобязательно-
Имя функции в
module, которую этот этап будет использовать для выполнения своей работы. Соответствующая функция шейдера должна иметь атрибут@vertex, чтобы быть идентифицированной как эта точка входа. См. Описание точки входа для получения дополнительной информации.Вы можете опустить свойство
entryPoint, если ваш код шейдера содержит единственную функцию с установленным атрибутом@vertex, — браузер будет использовать ее в качестве точки входа по умолчанию. ЕслиentryPointопущено, и браузер не может определить точку входа по умолчанию, генерируетсяGPUValidationError, и результирующийGPURenderPipelineбудет недействительным. module-
Объект
GPUShaderModule, содержащий код WGSL, который будет выполняться этим программируемым этапом. buffersНеобязательно-
Массив объектов, каждый из которых представляет ожидаемую структуру буфера вершин, используемого в конвейере. Каждый объект может содержать следующие свойства:
arrayStride-
Число, представляющее шаг (в байтах) между различными структурами (например, вершинами) внутри буфера.
attributes-
Массив объектов, определяющих структуру атрибутов вершин в каждой структуре. Каждый объект имеет следующие свойства:
format-
Перечисление, определяющее формат вершины. Все доступные значения см. в
GPUVertexFormatопределении в спецификации. offset-
Число, указывающее смещение (в байтах) от начала структуры до данных для атрибута.
shaderLocation-
Числовой идентификатор, соответствующий этому атрибуту, который будет соответствовать атрибуту
@location, объявленному в коде WGSL связанногоGPUShaderModule, указанного в свойствеvertexобъектаmodule.
stepModeНеобязательно-
Перечисление, определяющее, представляют ли отдельные структуры внутри буфера вершины или экземпляры. Возможные значения:
-
"instance": Каждая структура — экземпляр; адрес увеличивается наarrayStrideдля каждого экземпляра. -
"vertex": Каждая структура — вершина; адрес увеличивается наarrayStrideдля каждой вершины и сбрасывается между экземплярами.
Если опущено,
stepModeпо умолчанию равно"vertex". -
Возвращаемое значение
Экземпляр объекта GPURenderPipeline.
Валидация
Следующие критерии должны быть соблюдены при вызове createRenderPipeline(), в противном случае генерируется GPUValidationError и возвращается недопустимый объект GPURenderPipeline:
- Для объектов
depthStencil:-
formatдолжен быть форматомdepth-or-stencil. - Свойства
depthBias,depthBiasClampиdepthBiasSlopeScaleдолжны быть установлены в0для топологий линий и точек, т.е. еслиtopologyустановлено в"line-list","line-strip"или"point-list". - Если
depthWriteEnabledравноtrueилиdepthCompareне равно"always",formatимеет компонент глубины. - Если свойства
stencilFrontилиstencilBackне имеют значения по умолчанию,formatимеет компонент трафарета.
-
- Для объектов
fragment:-
targets.lengthдолжно быть меньше или равно предельному значениюmaxColorAttachmentsGPUDevice(см. предел). - Для каждого
target, численное значениеwriteMaskдолжно быть меньше или равно 16. - Если какие-либо используемые операции смешивания используют альфа-канал источника (например,
"src-alpha-saturated"), выходное изображение должно иметь альфа-канал (т.е. это должно бытьvec4). - Если используются операции смешивания
src1,one-minus-src1,src1-alphaилиone-minus-src1-alpha, то функцияdual-source-blendingподдерживается. - Если свойство
entryPointопущено, код шейдера содержит единственную функцию входа фрагментного шейдера, которую браузер может использовать в качестве функции входа по умолчанию.
-
- Для объектов
primitive:- Если используется свойство
unclippedDepth, то функцияdepth-clip-controlподдерживается.
- Если используется свойство
- Для объектов
vertex:- Если свойство
entryPointопущено, код шейдера содержит единственную функцию входа вершинного шейдера, которую браузер может использовать в качестве функции входа по умолчанию.
- Если свойство
Примеры
Примечание: В примерах WebGPU представлено множество других примеров.
Базовый пример
Наш базовый демонстрационный пример рендеринга демонстрирует создание описателя объекта рендеринга, который затем используется для создания GPURenderPipeline через вызов createRenderPipeline().
// ...
const vertexBuffers = [
{
attributes: [
{
shaderLocation: 0, // position
offset: 0,
format: "float32x4",
},
{
shaderLocation: 1, // color
offset: 16,
format: "float32x4",
},
],
arrayStride: 32,
stepMode: "vertex",
},
];
const pipelineDescriptor = {
vertex: {
module: shaderModule,
entryPoint: "vertex_main",
buffers: vertexBuffers,
},
fragment: {
module: shaderModule,
entryPoint: "fragment_main",
targets: [
{
format: navigator.gpu.getPreferredCanvasFormat(),
},
],
},
primitive: {
topology: "triangle-list",
},
layout: "auto",
};
const renderPipeline = device.createRenderPipeline(pipelineDescriptor);
// ...
Спецификации
| Спецификация |
|---|
| WebGPU # dom-gpudevice-createrenderpipeline |
Совместимость с браузерами
| Десктопные | Мобильные | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari на iOS | Samsung Internet | WebView Android | |
createRenderPipeline |
113В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
113В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
previewВ настоящее время поддерживается только на Linux и Windows. |
99В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
preview | 121 | Нет | 81 | Нет | 25.0 | 121 |
dual-source-blending |
130В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
130В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 115В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 130 | Нет | 86 | Нет | Нет | 130 |
optional_depthcompare_depthwriteenabled |
120В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
120В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 106В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 121 | Нет | 81 | Нет | 25.0 | 121 |
optional_entryPoint |
121В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
121В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 107В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 121В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 81В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 25.0В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
121В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
texture_rgb10a2uint |
119В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
119В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 105В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 121 | Нет | 81 | Нет | 25.0 | 121 |
validates_depth_bias_for_line_and_point_topologies |
131В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
131В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 116В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 131В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | Нет | Нет | Нет | 131В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
vertex_unorm10-10-10-2 |
119В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
119В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 105В настоящее время поддерживается только на ChromeOS, macOS и Windows. |
Нет | 121 | Нет | 81 | Нет | 25.0 | 121 |
См. также
- API WebGPU
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/GPUDevice/createRenderPipeline