Changeset 245905 in webkit
- Timestamp:
- May 30, 2019 2:05:16 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 29 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r245902 r245905 1 2019-05-30 Justin Fan <justin_fan@apple.com> 2 3 [Web GPU] Vertex Buffers/Input State API updates 4 https://bugs.webkit.org/show_bug.cgi?id=194258 5 <rdar://problem/47806127> 6 7 Reviewed by Myles C. Maxfield. 8 9 Update WebGPU tests for the new vertex buffer attributes model. 10 11 * webgpu/blend-triangle-strip.html: 12 * webgpu/buffer-command-buffer-races.html: 13 * webgpu/buffer-resource-triangles.html: 14 * webgpu/depth-enabled-triangle-strip.html: 15 * webgpu/draw-indexed-triangles.html: 16 * webgpu/js/webgpu-functions.js: 17 * webgpu/texture-triangle-strip.html: 18 * webgpu/vertex-buffer-triangle-strip.html: 19 * webgpu/whlsl-arbitrary-vertex-attribute-locations.html: 20 * webgpu/whlsl-dereference-pointer-should-type-check.html: 21 * webgpu/whlsl-dont-crash-parsing-enum.html: 22 * webgpu/whlsl-dot-expressions.html: 23 * webgpu/whlsl-nested-dot-expression-rvalue.html: 24 * webgpu/whlsl.html: 25 1 26 2019-05-30 Wenson Hsieh <wenson_hsieh@apple.com> 2 27 -
trunk/LayoutTests/webgpu/blend-triangle-strip.html
r244507 r245905 57 57 }]; 58 58 59 const inputStateDescriptor = {59 const vertexInputDescriptor = { 60 60 indexFormat: "uint32", 61 attributes: [{ 62 shaderLocation: positionAttributeNum, 63 inputSlot: 0, 64 format: "float4" 65 }], 66 inputs: [{ 67 inputSlot: 0, 68 stride: 4 * 4 61 vertexBuffers: [{ 62 stride: 4 * 4, 63 attributeSet: [{ 64 format: "float4", 65 shaderLocation: positionAttributeNum 66 }] 69 67 }] 70 68 }; 71 69 72 const pipeline = createBasicPipeline(shaderModule, device, colorStates, null, inputStateDescriptor);70 const pipeline = createBasicPipeline(shaderModule, device, colorStates, null, vertexInputDescriptor); 73 71 74 72 const vertexData = new Float32Array([ -
trunk/LayoutTests/webgpu/buffer-command-buffer-races.html
r244442 r245905 43 43 ` 44 44 45 function create InputStateDescriptor() {45 function createVertexInputDescriptor() { 46 46 return { 47 47 indexFormat: "uint32", 48 attributes: [{ 49 shaderLocation: 0, 50 inputSlot: 0, 51 format: "float2" 48 vertexBuffers: [{ 49 stride: 4 * 2, 50 attributeSet: [{ 51 format: "float2", 52 shaderLocation: 0 53 }] 52 54 }, { 53 shaderLocation: 1,54 inputSlot: 1,55 format: "float3"56 }],57 inputs: [{58 inputSlot: 0,59 stride: 4 * 260 }, {61 inputSlot: 1,62 55 stride: 4 * 3, 63 stepMode: "instance" 56 stepMode: "instance", 57 attributeSet: [{ 58 format: "float3", 59 shaderLocation: 1 60 }] 64 61 }] 65 62 } … … 89 86 // FIXME: Replace with non-MSL shaders. 90 87 const shaderModule = device.createShaderModule({ code: shaderCode }); 91 const inputStateDescriptor = createInputStateDescriptor();92 const pipeline = createBasicPipeline(shaderModule, device, null, null, inputStateDescriptor);88 const vertexInputDescriptor = createVertexInputDescriptor(); 89 const pipeline = createBasicPipeline(shaderModule, device, null, null, vertexInputDescriptor); 93 90 94 91 const upperLeftBuffer = createAndSetVertexBuffer(device, [-1, 1, -1, -1, 0, 1]); -
trunk/LayoutTests/webgpu/buffer-resource-triangles.html
r244856 r245905 133 133 134 134 // Create vertex input state. 135 const inputState= {135 const vertexInput = { 136 136 indexFormat: "uint32", 137 attributes: [{ 138 shaderLocation: 0, 139 inputSlot: 0, 140 format: "float4" 141 }], 142 inputs: [{ 143 inputSlot: 0, 144 stride: vertexSize 137 vertexBuffers: [{ 138 stride: vertexSize, 139 attributeSet: [{ 140 format: "float4", 141 shaderLocation: 0 142 }] 145 143 }] 146 144 }; … … 160 158 // GPUPipelineLayout and GPURenderPipeline 161 159 const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [leftTriangleBGLayout, rightTriangleBGLayout] }); 162 const pipeline = createBasicPipeline(shaderModule, device, null, pipelineLayout, inputState, null, "triangle-list");160 const pipeline = createBasicPipeline(shaderModule, device, null, pipelineLayout, vertexInput, null, "triangle-list"); 163 161 164 162 // GPUBufferBindings -
trunk/LayoutTests/webgpu/depth-enabled-triangle-strip.html
r244442 r245905 63 63 } 64 64 65 function create InputStateDescriptor() {65 function createVertexInputDescriptor() { 66 66 return { 67 67 indexFormat: "uint32", 68 attributes: [{ 69 shaderLocation: 0, 70 inputSlot: 0, 71 format: "float4" 72 }], 73 inputs: [{ 74 inputSlot: 0, 75 stride: 4 * 4 68 vertexBuffers: [{ 69 stride: 4 * 4, 70 attributeSet: [{ 71 format: "float4", 72 shaderLocation: 0 73 }] 76 74 }] 77 75 } … … 85 83 const shaderModule = device.createShaderModule({ code: shaderCode }); 86 84 const vertexBuffer = createVertexBuffer(device); 87 const inputStateDescriptor = createInputStateDescriptor();85 const vertexInputDescriptor = createVertexInputDescriptor(); 88 86 const depthStateDescriptor = createBasicDepthStateDescriptor(); 89 const pipeline = createBasicPipeline(shaderModule, device, null, null, inputStateDescriptor, depthStateDescriptor);87 const pipeline = createBasicPipeline(shaderModule, device, null, null, vertexInputDescriptor, depthStateDescriptor); 90 88 const commandEncoder = device.createCommandEncoder(); 91 89 -
trunk/LayoutTests/webgpu/draw-indexed-triangles.html
r244442 r245905 72 72 } 73 73 74 function create InputStateDescriptor() {74 function createVertexInputDescriptor() { 75 75 return { 76 76 indexFormat: "uint32", 77 attributes: [{ 78 shaderLocation: 0, 79 inputSlot: 0, 80 format: "float4" 81 }, { 82 shaderLocation: 1, 83 inputSlot: 0, 84 offset: 4 * 4, 85 format: "float" 86 }], 87 inputs: [{ 88 inputSlot: 0, 89 stride: 4 * 5 77 vertexBuffers: [{ 78 stride: 4 * 5, 79 attributeSet: [{ 80 format: "float4", 81 shaderLocation: 0 82 }, { 83 offset: 4 * 4, 84 format: "float", 85 shaderLocation: 1 86 }] 90 87 }] 91 88 }; … … 100 97 const vertexBuffer = createVertexBuffer(device); 101 98 const indexBuffer = createIndexBuffer(device); 102 const pipeline = createBasicPipeline(shaderModule, device, null, null, create InputStateDescriptor(), null, "triangle-list");99 const pipeline = createBasicPipeline(shaderModule, device, null, null, createVertexInputDescriptor(), null, "triangle-list"); 103 100 const commandEncoder = device.createCommandEncoder(); 104 101 const passEncoder = beginBasicRenderPass(swapChain, commandEncoder); -
trunk/LayoutTests/webgpu/js/webgpu-functions.js
r244856 r245905 31 31 } 32 32 33 function createBasicPipeline(shaderModule, device, colorStates, pipelineLayout, inputStateDescriptor, depthStateDescriptor, primitiveTopology = "triangle-strip") {33 function createBasicPipeline(shaderModule, device, colorStates, pipelineLayout, vertexInputDescriptor, depthStateDescriptor, primitiveTopology = "triangle-strip") { 34 34 const vertexStageDescriptor = { 35 35 module: shaderModule, … … 50 50 } 51 51 52 if (! inputStateDescriptor)53 inputStateDescriptor = { attributes: [], inputs: [] };52 if (!vertexInputDescriptor) 53 vertexInputDescriptor = { vertexBuffers: [] }; 54 54 55 55 const pipelineDescriptor = { … … 58 58 primitiveTopology: primitiveTopology, 59 59 colorStates: colorStates, 60 inputState: inputStateDescriptor60 vertexInput: vertexInputDescriptor 61 61 }; 62 62 -
trunk/LayoutTests/webgpu/texture-triangle-strip.html
r244442 r245905 56 56 ` 57 57 58 function createInputStateDescriptor() { 59 return { 60 indexFormat: "uint32", 61 attributes: [{ 62 shaderLocation: positionAttributeNum, 63 inputSlot: positionBufferIndex, 64 format: "float4" 65 }, { 66 shaderLocation: texCoordsAttributeNum, 67 inputSlot: texCoordsBufferIndex, 68 format: "float2" 69 }], 70 inputs: [{ 71 inputSlot: positionBufferIndex, 72 stride: 4 * 4 73 }, { 74 inputSlot: texCoordsBufferIndex, 75 stride: 4 * 2 58 function createVertexInputDescriptor() { 59 var bufferDescriptors = []; 60 bufferDescriptors[positionBufferIndex] = { 61 stride: 4 * 4, 62 attributeSet: [{ 63 format: "float4", 64 shaderLocation: positionAttributeNum 76 65 }] 77 } 66 }; 67 bufferDescriptors[texCoordsBufferIndex] = { 68 stride: 4 * 2, 69 attributeSet: [{ 70 format: "float2", 71 shaderLocation: texCoordsAttributeNum 72 }] 73 }; 74 75 return { vertexBuffers: bufferDescriptors }; 78 76 } 79 77 … … 105 103 textureCoordBuffer.setSubData(0, texCoordsArray.buffer); 106 104 107 const inputStateDescriptor = createInputStateDescriptor();105 const vertexInputDescriptor = createVertexInputDescriptor(); 108 106 109 107 // Load texture image … … 178 176 179 177 // Pipeline and render 180 const pipeline = createBasicPipeline(shaderModule, device, null, pipelineLayout, inputStateDescriptor);178 const pipeline = createBasicPipeline(shaderModule, device, null, pipelineLayout, vertexInputDescriptor); 181 179 const commandEncoder = device.createCommandEncoder(); 182 180 -
trunk/LayoutTests/webgpu/vertex-buffer-triangle-strip.html
r244442 r245905 61 61 } 62 62 63 function create InputStateDescriptor() {63 function createVertexInputDescriptor() { 64 64 return { 65 indexFormat: "uint32", 66 attributes: [{ 67 shaderLocation: 0, 68 inputSlot: 0, 69 format: "float4" 70 }, { 71 shaderLocation: 1, 72 inputSlot: 0, 73 offset: 4 * 4, 74 format: "float" 75 }], 76 inputs: [{ 77 inputSlot: 0, 78 stride: 4 * 5 65 vertexBuffers: [{ 66 stride: 4 * 5, 67 attributeSet: [{ 68 format: "float4", 69 shaderLocation: 0 70 }, { 71 offset: 4 * 4, 72 format: "float", 73 shaderLocation: 1 74 }] 79 75 }] 80 76 } … … 88 84 const shaderModule = device.createShaderModule({ code: shaderCode }); 89 85 const vertexBuffer = createVertexBuffer(device); 90 const inputStateDescriptor = createInputStateDescriptor();91 const pipeline = createBasicPipeline(shaderModule, device, null, null, inputStateDescriptor);86 const vertexInputDescriptor = createVertexInputDescriptor(); 87 const pipeline = createBasicPipeline(shaderModule, device, null, null, vertexInputDescriptor); 92 88 const commandEncoder = device.createCommandEncoder(); 93 89 const passEncoder = beginBasicRenderPass(swapChain, commandEncoder); -
trunk/LayoutTests/webgpu/whlsl-arbitrary-vertex-attribute-locations.html
r245759 r245905 37 37 const depthStencilState = null; 38 38 39 const attribute0 = {shaderLocation: 173, inputSlot: 0, format: "float4", offset: 0}; 40 const attribute1 = {shaderLocation: 498, inputSlot: 0, format: "float", offset: 16}; 41 const attributes = [attribute0, attribute1]; 42 const input0 = {inputSlot: 0, stride: 20 }; 39 const attribute0 = {shaderLocation: 173, format: "float4"}; 40 const attribute1 = {shaderLocation: 498, format: "float", offset: 16}; 41 const input0 = {stride: 20, attributeSet: [attribute0, attribute1]}; 43 42 const inputs = [input0]; 44 const inputState = {indexFormat: "uint32", attributes,inputs};43 const vertexInput = {vertexBuffers: inputs}; 45 44 46 45 const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]}; … … 49 48 const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor); 50 49 51 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, inputState, sampleCount: 1, layout: pipelineLayout};50 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout}; 52 51 const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor); 53 52 -
trunk/LayoutTests/webgpu/whlsl-dereference-pointer-should-type-check.html
r245844 r245905 42 42 const depthStencilState = null; 43 43 44 const attribute0 = {shaderLocation: 0, inputSlot: 0,format: "float4", offset: 0};45 const attribute1 = {shaderLocation: 1, inputSlot: 0,format: "float", offset: 16};44 const attribute0 = {shaderLocation: 0, format: "float4", offset: 0}; 45 const attribute1 = {shaderLocation: 1, format: "float", offset: 16}; 46 46 const attributes = [attribute0, attribute1]; 47 const input0 = { inputSlot: 0, stride: 20};47 const input0 = {stride: 20, attributeSet: attributes}; 48 48 const inputs = [input0]; 49 const inputState = {indexFormat: "uint32", attributes,inputs};49 const vertexInput = {vertexBuffers: inputs}; 50 50 51 51 const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]}; … … 54 54 const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor); 55 55 56 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, inputState, sampleCount: 1, layout: pipelineLayout};56 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout}; 57 57 const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor); 58 58 -
trunk/LayoutTests/webgpu/whlsl-dont-crash-parsing-enum.html
r245662 r245905 34 34 const depthStencilState = null; 35 35 36 const attribute0 = {shaderLocation: 0, inputSlot: 0, format: "float4"}; 37 const attribute1 = {shaderLocation: 1, inputSlot: 1, format: "float"}; 38 const attributes = [attribute0, attribute1]; 39 const input0 = {inputSlot: 0, stride: 16 }; 40 const input1 = {inputSlot: 1, stride: 4 }; 36 const attribute0 = {shaderLocation: 0, format: "float4"}; 37 const attribute1 = {shaderLocation: 1, format: "float"}; 38 const input0 = {stride: 16, attributeSet: [attribute0]}; 39 const input1 = {stride: 4, attributeSet: [attribute1]}; 41 40 const inputs = [input0, input1]; 42 const inputState = {indexFormat: "uint32", attributes,inputs};41 const vertexInput = {vertexBuffers: inputs}; 43 42 44 43 const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]}; … … 47 46 const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor); 48 47 49 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, inputState, sampleCount: 1, layout: pipelineLayout};48 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout}; 50 49 const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor); 51 50 -
trunk/LayoutTests/webgpu/whlsl-dot-expressions.html
r245680 r245905 37 37 const depthStencilState = null; 38 38 39 const attribute0 = {shaderLocation: 0, inputSlot: 0, format: "float4", offset: 0};40 const attribute1 = {shaderLocation: 1, inputSlot: 0,format: "float", offset: 16};39 const attribute0 = {shaderLocation: 0, format: "float4"}; 40 const attribute1 = {shaderLocation: 1, format: "float", offset: 16}; 41 41 const attributes = [attribute0, attribute1]; 42 const input0 = { inputSlot: 0, stride: 20};42 const input0 = {stride: 20, attributeSet: attributes}; 43 43 const inputs = [input0]; 44 const inputState = {indexFormat: "uint32", attributes,inputs};44 const vertexInput = {vertexBuffers: inputs}; 45 45 46 46 const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]}; … … 49 49 const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor); 50 50 51 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, inputState, sampleCount: 1, layout: pipelineLayout};51 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout}; 52 52 const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor); 53 53 -
trunk/LayoutTests/webgpu/whlsl-nested-dot-expression-rvalue.html
r245721 r245905 51 51 const depthStencilState = null; 52 52 53 const attribute0 = {shaderLocation: 0, inputSlot: 0, format: "float4", offset: 0};54 const attribute1 = {shaderLocation: 1, inputSlot: 0,format: "float", offset: 16};53 const attribute0 = {shaderLocation: 0, format: "float4"}; 54 const attribute1 = {shaderLocation: 1, format: "float", offset: 16}; 55 55 const attributes = [attribute0, attribute1]; 56 const input0 = { inputSlot: 0, stride: 20};56 const input0 = {stride: 20, attributeSet: attributes}; 57 57 const inputs = [input0]; 58 const inputState = {indexFormat: "uint32", attributes,inputs};58 const vertexInput = {vertexBuffers: inputs}; 59 59 60 60 const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]}; … … 63 63 const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor); 64 64 65 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, inputState, sampleCount: 1, layout: pipelineLayout};65 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout}; 66 66 const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor); 67 67 -
trunk/LayoutTests/webgpu/whlsl.html
r244777 r245905 29 29 const depthStencilState = null; 30 30 31 const attribute0 = {shaderLocation: 0, inputSlot: 0, format: "float4"}; 32 const attribute1 = {shaderLocation: 1, inputSlot: 1, format: "float"}; 33 const attributes = [attribute0, attribute1]; 34 const input0 = {inputSlot: 0, stride: 16 }; 35 const input1 = {inputSlot: 1, stride: 4 }; 31 const attribute0 = {shaderLocation: 0, format: "float4"}; 32 const attribute1 = {shaderLocation: 1, format: "float"}; 33 const input0 = {stride: 16, attributeSet: [attribute0]}; 34 const input1 = {stride: 4, attributeSet: [attribute1]}; 36 35 const inputs = [input0, input1]; 37 const inputState = {indexFormat: "uint32", attributes,inputs};36 const vertexInput = {vertexBuffers: inputs}; 38 37 39 38 const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]}; … … 42 41 const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor); 43 42 44 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, inputState, sampleCount: 1, layout: pipelineLayout};43 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout}; 45 44 const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor); 46 45 -
trunk/Source/WebCore/CMakeLists.txt
r245638 r245905 481 481 Modules/webgpu/GPUDepthStencilStateDescriptor.idl 482 482 Modules/webgpu/GPUExtent3D.idl 483 Modules/webgpu/GPUInputStateDescriptor.idl484 483 Modules/webgpu/GPULoadOp.idl 485 484 Modules/webgpu/GPUOrigin3D.idl … … 492 491 Modules/webgpu/GPUTextureUsage.idl 493 492 Modules/webgpu/GPUVertexAttributeDescriptor.idl 493 Modules/webgpu/GPUVertexBufferDescriptor.idl 494 494 Modules/webgpu/GPUVertexInputDescriptor.idl 495 495 Modules/webgpu/NavigatorGPU.idl -
trunk/Source/WebCore/ChangeLog
r245900 r245905 1 2019-05-30 Justin Fan <justin_fan@apple.com> 2 3 [Web GPU] Vertex Buffers/Input State API updates 4 https://bugs.webkit.org/show_bug.cgi?id=194258 5 <rdar://problem/47806127> 6 7 Reviewed by Myles C. Maxfield. 8 9 The vertex buffer attributes model for GPURenderPipelines in the WebGPU API has been updated. 10 Update our implementation to match. 11 12 No new tests. Existing tests updated to match new behavior. 13 14 * CMakeLists.txt: 15 * DerivedSources-input.xcfilelist: 16 * DerivedSources-output.xcfilelist: 17 * DerivedSources.make: 18 * Modules/webgpu/GPUVertexAttributeDescriptor.idl: 19 * Modules/webgpu/GPUVertexBufferDescriptor.idl: Renamed from Source/WebCore/Modules/webgpu/GPUInputStateDescriptor.idl. 20 * Modules/webgpu/GPUVertexInputDescriptor.idl: 21 * Modules/webgpu/WebGPURenderPipelineDescriptor.idl: 22 * Sources.txt: 23 * WebCore.xcodeproj/project.pbxproj: 24 * platform/graphics/gpu/GPURenderPipelineDescriptor.h: 25 * platform/graphics/gpu/GPUVertexAttributeDescriptor.h: 26 * platform/graphics/gpu/GPUVertexBufferDescriptor.h: Renamed from Source/WebCore/platform/graphics/gpu/GPUInputStateDescriptor.h. 27 * platform/graphics/gpu/GPUVertexInputDescriptor.h: 28 * platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm: 29 (WebCore::trySetVertexInput): Added. Populate Metal and WHLSL pipeline descriptors with vertex attribute metadata. 30 (WebCore::trySetColorStates): Added. Populate Metal and WHLSL pipeline descriptors with color attachment metadata. 31 (WebCore::convertLayout): Moved. 32 (WebCore::trySetMetalFunctions): Moved. 33 (WebCore::trySetFunctions): Added. WHLSL compilation to Metal SL happens here, then MSL functions are set on pipeline descriptor. 34 (WebCore::convertRenderPipelineDescriptor): Repurposed. Convert a GPURenderPipelineDescriptor to Metal and WHLSL versions. 35 (WebCore::tryCreateMtlRenderPipelineState): 36 (WebCore::GPURenderPipeline::tryCreate): 37 (WebCore::trySetMetalFunctionsForPipelineDescriptor): Deleted. 38 (WebCore::trySetWHLSLFunctionsForPipelineDescriptor): Deleted. 39 (WebCore::trySetFunctionsForPipelineDescriptor): Deleted. 40 (WebCore::trySetInputStateForPipelineDescriptor): Deleted. 41 (WebCore::setColorStatesForColorAttachmentArray): Deleted. 42 1 43 2019-05-30 Zalan Bujtas <zalan@apple.com> 2 44 -
trunk/Source/WebCore/DerivedSources-input.xcfilelist
r245638 r245905 343 343 $(PROJECT_DIR)/Modules/webgpu/GPUTextureUsage.idl 344 344 $(PROJECT_DIR)/Modules/webgpu/GPUVertexAttributeDescriptor.idl 345 $(PROJECT_DIR)/Modules/webgpu/GPUVertexBufferDescriptor.idl 345 346 $(PROJECT_DIR)/Modules/webgpu/GPUVertexInputDescriptor.idl 346 347 $(PROJECT_DIR)/Modules/webgpu/NavigatorGPU.idl -
trunk/Source/WebCore/DerivedSources-output.xcfilelist
r245638 r245905 634 634 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUVertexAttributeDescriptor.cpp 635 635 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUVertexAttributeDescriptor.h 636 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUVertexBufferDescriptor.cpp 637 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUVertexBufferDescriptor.h 636 638 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUVertexInputDescriptor.cpp 637 639 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUVertexInputDescriptor.h -
trunk/Source/WebCore/DerivedSources.make
r245638 r245905 389 389 $(WebCore)/Modules/webgpu/GPUExtent3D.idl \ 390 390 $(WebCore)/Modules/webgpu/GPULoadOp.idl \ 391 $(WebCore)/Modules/webgpu/GPUInputStateDescriptor.idl \392 391 $(WebCore)/Modules/webgpu/GPUOrigin3D.idl \ 393 392 $(WebCore)/Modules/webgpu/GPURequestAdapterOptions.idl \ … … 399 398 $(WebCore)/Modules/webgpu/GPUTextureUsage.idl \ 400 399 $(WebCore)/Modules/webgpu/GPUVertexAttributeDescriptor.idl \ 400 $(WebCore)/Modules/webgpu/GPUVertexBufferDescriptor.idl \ 401 401 $(WebCore)/Modules/webgpu/GPUVertexInputDescriptor.idl \ 402 402 $(WebCore)/Modules/webgpu/NavigatorGPU.idl \ -
trunk/Source/WebCore/Modules/webgpu/GPUVertexAttributeDescriptor.idl
r244442 r245905 41 41 EnabledAtRuntime=WebGPU 42 42 ] dictionary GPUVertexAttributeDescriptor { 43 required u32 shaderLocation;44 required u32 inputSlot;45 43 u64 offset = 0; 46 44 required GPUVertexFormat format; 45 required u32 shaderLocation; 47 46 }; -
trunk/Source/WebCore/Modules/webgpu/GPUVertexBufferDescriptor.idl
r245904 r245905 1 1 /* 2 * Copyright (C) 201 8Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 27 27 typedef unsigned long u32; 28 typedef unsigned long long u64; 28 29 29 30 [ 30 ImplementedAs=GPUIn dexFormat31 ] enum GPUIn dexFormat{32 " uint16",33 " uint32"31 ImplementedAs=GPUInputStepMode 32 ] enum GPUInputStepMode { 33 "vertex", 34 "instance" 34 35 }; 35 36 … … 37 38 Conditional=WEBGPU, 38 39 EnabledAtRuntime=WebGPU 39 ] dictionary GPUInputStateDescriptor { 40 GPUIndexFormat? indexFormat; 41 42 required sequence<GPUVertexAttributeDescriptor> attributes; 43 required sequence<GPUVertexInputDescriptor> inputs; 40 ] dictionary GPUVertexBufferDescriptor { 41 required u64 stride; 42 GPUInputStepMode stepMode = "vertex"; 43 sequence<GPUVertexAttributeDescriptor> attributeSet; 44 44 }; -
trunk/Source/WebCore/Modules/webgpu/GPUVertexInputDescriptor.idl
r244442 r245905 26 26 27 27 typedef unsigned long u32; 28 typedef unsigned long long u64;29 28 30 29 [ 31 ImplementedAs=GPUIn putStepMode32 ] enum GPUIn putStepMode{33 " vertex",34 " instance"30 ImplementedAs=GPUIndexFormat 31 ] enum GPUIndexFormat { 32 "uint16", 33 "uint32" 35 34 }; 36 35 … … 39 38 EnabledAtRuntime=WebGPU 40 39 ] dictionary GPUVertexInputDescriptor { 41 required u32 inputSlot; 42 required u64 stride; 43 GPUInputStepMode stepMode = "vertex"; 40 GPUIndexFormat indexFormat = "uint32"; 41 required sequence<GPUVertexBufferDescriptor?> vertexBuffers; 44 42 }; -
trunk/Source/WebCore/Modules/webgpu/WebGPURenderPipelineDescriptor.idl
r244442 r245905 45 45 required sequence<GPUColorStateDescriptor> colorStates; 46 46 GPUDepthStencilStateDescriptor? depthStencilState = null; 47 required GPU InputStateDescriptor inputState;47 required GPUVertexInputDescriptor vertexInput; 48 48 }; -
trunk/Source/WebCore/Sources.txt
r245850 r245905 2748 2748 JSGPUDepthStencilStateDescriptor.cpp 2749 2749 JSGPUExtent3D.cpp 2750 JSGPUInputStateDescriptor.cpp2751 2750 JSGPULoadOp.cpp 2752 2751 JSGPUOrigin3D.cpp … … 2759 2758 JSGPUTextureUsage.cpp 2760 2759 JSGPUVertexAttributeDescriptor.cpp 2760 JSGPUVertexBufferDescriptor.cpp 2761 2761 JSGPUVertexInputDescriptor.cpp 2762 2762 JSGainNode.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r245850 r245905 14029 14029 D0D8649121B760C4003C983C /* GPUBufferMetal.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = GPUBufferMetal.mm; sourceTree = "<group>"; }; 14030 14030 D0D8649221B760F2003C983C /* GPUBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUBuffer.h; sourceTree = "<group>"; }; 14031 D0D8649421BA173D003C983C /* GPU InputStateDescriptor.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = GPUInputStateDescriptor.idl; sourceTree = "<group>"; };14031 D0D8649421BA173D003C983C /* GPUVertexInputDescriptor.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = GPUVertexInputDescriptor.idl; sourceTree = "<group>"; }; 14032 14032 D0D8649621BA18F4003C983C /* GPUVertexAttributeDescriptor.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = GPUVertexAttributeDescriptor.idl; sourceTree = "<group>"; }; 14033 D0D8649821BA19A7003C983C /* GPUVertex InputDescriptor.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = GPUVertexInputDescriptor.idl; sourceTree = "<group>"; };14034 D0D8649921BA1B1F003C983C /* GPU InputStateDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUInputStateDescriptor.h; sourceTree = "<group>"; };14033 D0D8649821BA19A7003C983C /* GPUVertexBufferDescriptor.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = GPUVertexBufferDescriptor.idl; sourceTree = "<group>"; }; 14034 D0D8649921BA1B1F003C983C /* GPUVertexInputDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUVertexInputDescriptor.h; sourceTree = "<group>"; }; 14035 14035 D0D8649B21BA1C2D003C983C /* GPUVertexAttributeDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUVertexAttributeDescriptor.h; sourceTree = "<group>"; }; 14036 D0D8649C21BA1CE8003C983C /* GPUVertex InputDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUVertexInputDescriptor.h; sourceTree = "<group>"; };14036 D0D8649C21BA1CE8003C983C /* GPUVertexBufferDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUVertexBufferDescriptor.h; sourceTree = "<group>"; }; 14037 14037 D0DA0BE4217930E2007FE2AC /* WebGPUSwapChain.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGPUSwapChain.h; sourceTree = "<group>"; }; 14038 14038 D0DA0BE5217930E2007FE2AC /* WebGPUSwapChain.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebGPUSwapChain.cpp; sourceTree = "<group>"; }; … … 18266 18266 312FF8BE21A4C2F100EB199D /* GPUDevice.h */, 18267 18267 D026F47D220A2AC600AC5F49 /* GPUExtent3D.h */, 18268 D0D8649921BA1B1F003C983C /* GPUInputStateDescriptor.h */,18269 18268 D0F7559F2203BA1400118058 /* GPULimits.h */, 18270 18269 D08AA02F220D0BD50058C502 /* GPULoadOp.h */, … … 18295 18294 D06EF552220BA26A0018724E /* GPUUtils.h */, 18296 18295 D0D8649B21BA1C2D003C983C /* GPUVertexAttributeDescriptor.h */, 18297 D0D8649C21BA1CE8003C983C /* GPUVertexInputDescriptor.h */, 18296 D0D8649C21BA1CE8003C983C /* GPUVertexBufferDescriptor.h */, 18297 D0D8649921BA1B1F003C983C /* GPUVertexInputDescriptor.h */, 18298 18298 498770D71242C535002226BA /* Texture.cpp */, 18299 18299 498770D81242C535002226BA /* Texture.h */, … … 25848 25848 D03C84A221FFD7230002227F /* GPUDepthStencilStateDescriptor.idl */, 25849 25849 D026F480220A2B7000AC5F49 /* GPUExtent3D.idl */, 25850 D0D8649421BA173D003C983C /* GPUInputStateDescriptor.idl */,25851 25850 D08AA02D220D0B9C0058C502 /* GPULoadOp.idl */, 25852 25851 D0CCA94922299F97006979B6 /* GPUOrigin3D.h */, … … 25861 25860 D026F483220A472F00AC5F49 /* GPUTextureUsage.idl */, 25862 25861 D0D8649621BA18F4003C983C /* GPUVertexAttributeDescriptor.idl */, 25863 D0D8649821BA19A7003C983C /* GPUVertexInputDescriptor.idl */, 25862 D0D8649821BA19A7003C983C /* GPUVertexBufferDescriptor.idl */, 25863 D0D8649421BA173D003C983C /* GPUVertexInputDescriptor.idl */, 25864 25864 D00487ED2274281300EED7D9 /* NavigatorGPU.cpp */, 25865 25865 D00487EE2274281400EED7D9 /* NavigatorGPU.h */, -
trunk/Source/WebCore/platform/graphics/gpu/GPURenderPipelineDescriptor.h
r244442 r245905 30 30 #include "GPUColorStateDescriptor.h" 31 31 #include "GPUDepthStencilStateDescriptor.h" 32 #include "GPUInputStateDescriptor.h"33 32 #include "GPUPipelineDescriptorBase.h" 34 33 #include "GPUPipelineStageDescriptor.h" 34 #include "GPUVertexInputDescriptor.h" 35 35 #include <wtf/Optional.h> 36 36 #include <wtf/Vector.h> … … 50 50 Vector<GPUColorStateDescriptor> colorStates; 51 51 Optional<GPUDepthStencilStateDescriptor> depthStencilState; 52 GPU InputStateDescriptor inputState;52 GPUVertexInputDescriptor vertexInput; 53 53 }; 54 54 -
trunk/Source/WebCore/platform/graphics/gpu/GPUVertexAttributeDescriptor.h
r243658 r245905 40 40 41 41 struct GPUVertexAttributeDescriptor { 42 unsigned shaderLocation;43 unsigned inputSlot;44 42 uint64_t offset; 45 43 GPUVertexFormat format; 44 unsigned shaderLocation; 46 45 }; 47 46 -
trunk/Source/WebCore/platform/graphics/gpu/GPUVertexBufferDescriptor.h
r245904 r245905 1 1 /* 2 * Copyright (C) 201 8Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 30 30 #include "GPUVertexAttributeDescriptor.h" 31 #include "GPUVertexInputDescriptor.h"32 31 #include <wtf/Vector.h> 33 32 34 33 namespace WebCore { 35 34 36 enum class GPUIn dexFormat{37 Uint16,38 Uint32,35 enum class GPUInputStepMode { 36 Vertex, 37 Instance, 39 38 }; 40 39 41 struct GPUInputStateDescriptor { 42 Optional<GPUIndexFormat> indexFormat; 43 44 Vector<GPUVertexAttributeDescriptor> attributes; 45 Vector<GPUVertexInputDescriptor> inputs; 40 struct GPUVertexBufferDescriptor { 41 uint64_t stride; 42 GPUInputStepMode stepMode; 43 Vector<GPUVertexAttributeDescriptor> attributeSet; 46 44 }; 47 45 -
trunk/Source/WebCore/platform/graphics/gpu/GPUVertexInputDescriptor.h
r243658 r245905 28 28 #if ENABLE(WEBGPU) 29 29 30 #include "GPUVertexBufferDescriptor.h" 31 #include <wtf/Vector.h> 32 30 33 namespace WebCore { 31 34 32 enum class GPUIn putStepMode{33 Vertex,34 Instance,35 enum class GPUIndexFormat { 36 Uint16, 37 Uint32, 35 38 }; 36 39 37 40 struct GPUVertexInputDescriptor { 38 unsigned inputSlot; 39 uint64_t stride; 40 GPUInputStepMode stepMode; 41 GPUIndexFormat indexFormat; 42 Vector<Optional<GPUVertexBufferDescriptor>> vertexBuffers; 41 43 }; 42 44 -
trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm
r245759 r245905 38 38 #import <wtf/BlockObjCExceptions.h> 39 39 #import <wtf/CheckedArithmetic.h> 40 #import <wtf/HashSet.h> 40 41 #import <wtf/OptionSet.h> 41 42 #import <wtf/Optional.h> … … 146 147 } 147 148 148 static Optional<WHLSL::Layout> convertLayout(const GPUPipelineLayout& layout)149 {150 WHLSL::Layout result;151 if (layout.bindGroupLayouts().size() > std::numeric_limits<unsigned>::max())152 return WTF::nullopt;153 for (size_t i = 0; i < layout.bindGroupLayouts().size(); ++i) {154 const auto& bindGroupLayout = layout.bindGroupLayouts()[i];155 WHLSL::BindGroup bindGroup;156 bindGroup.name = static_cast<unsigned>(i);157 for (const auto& keyValuePair : bindGroupLayout->bindingsMap()) {158 const auto& gpuBindGroupLayoutBinding = keyValuePair.value;159 WHLSL::Binding binding;160 binding.visibility = convertShaderStageFlags(gpuBindGroupLayoutBinding.visibility);161 if (auto bindingType = convertBindingType(gpuBindGroupLayoutBinding.type))162 binding.bindingType = *bindingType;163 else164 return WTF::nullopt;165 if (gpuBindGroupLayoutBinding.binding > std::numeric_limits<unsigned>::max())166 return WTF::nullopt;167 binding.name = static_cast<unsigned>(gpuBindGroupLayoutBinding.binding);168 bindGroup.bindings.append(WTFMove(binding));169 }170 result.append(WTFMove(bindGroup));171 }172 return result;173 }174 175 static Optional<WHLSL::RenderPipelineDescriptor> convertRenderPipelineDescriptor(const GPURenderPipelineDescriptor& descriptor)176 {177 WHLSL::RenderPipelineDescriptor whlslDescriptor;178 if (descriptor.inputState.attributes.size() > std::numeric_limits<unsigned>::max())179 return WTF::nullopt;180 if (descriptor.colorStates.size() > std::numeric_limits<unsigned>::max())181 return WTF::nullopt;182 183 for (size_t i = 0; i < descriptor.inputState.attributes.size(); ++i)184 whlslDescriptor.vertexAttributes.append({ convertVertexFormat(descriptor.inputState.attributes[i].format), descriptor.inputState.attributes[i].shaderLocation, static_cast<unsigned>(i) });185 186 for (size_t i = 0; i < descriptor.colorStates.size(); ++i) {187 if (auto format = convertTextureFormat(descriptor.colorStates[i].format))188 whlslDescriptor.attachmentsStateDescriptor.attachmentDescriptors.append({*format, static_cast<unsigned>(i)});189 else190 return WTF::nullopt;191 }192 193 // FIXME: depthStencilAttachmentDescriptor isn't implemented yet.194 195 if (descriptor.layout) {196 if (auto layout = convertLayout(*descriptor.layout))197 whlslDescriptor.layout = WTFMove(*layout);198 else199 return WTF::nullopt;200 }201 whlslDescriptor.vertexEntryPointName = descriptor.vertexStage.entryPoint;202 if (descriptor.fragmentStage)203 whlslDescriptor.fragmentEntryPointName = descriptor.fragmentStage->entryPoint;204 return whlslDescriptor;205 }206 207 static bool trySetMetalFunctionsForPipelineDescriptor(const char* const functionName, MTLLibrary *vertexMetalLibrary, MTLLibrary *fragmentMetalLibrary, MTLRenderPipelineDescriptor *mtlDescriptor, const String& vertexEntryPointName, const String& fragmentEntryPointName)208 {209 #if LOG_DISABLED210 UNUSED_PARAM(functionName);211 #endif212 213 {214 BEGIN_BLOCK_OBJC_EXCEPTIONS;215 216 // Metal requires a vertex shader in all render pipelines.217 if (!vertexMetalLibrary) {218 LOG(WebGPU, "%s: MTLLibrary for vertex stage does not exist!", functionName);219 return false;220 }221 222 auto function = adoptNS([vertexMetalLibrary newFunctionWithName:vertexEntryPointName]);223 if (!function) {224 LOG(WebGPU, "%s: Cannot create vertex MTLFunction \"%s\"!", functionName, vertexEntryPointName.utf8().data());225 return false;226 }227 228 [mtlDescriptor setVertexFunction:function.get()];229 230 END_BLOCK_OBJC_EXCEPTIONS;231 }232 233 {234 BEGIN_BLOCK_OBJC_EXCEPTIONS;235 236 // However, fragment shaders are optional.237 if (!fragmentMetalLibrary)238 return true;239 240 auto function = adoptNS([fragmentMetalLibrary newFunctionWithName:fragmentEntryPointName]);241 242 if (!function) {243 LOG(WebGPU, "%s: Cannot create fragment MTLFunction \"%s\"!", functionName, fragmentEntryPointName.utf8().data());244 return false;245 }246 247 [mtlDescriptor setFragmentFunction:function.get()];248 return true;249 250 END_BLOCK_OBJC_EXCEPTIONS;251 }252 253 return false;254 }255 256 static bool trySetWHLSLFunctionsForPipelineDescriptor(const char* const functionName, MTLRenderPipelineDescriptor *mtlDescriptor, const GPURenderPipelineDescriptor& descriptor, String whlslSource, const GPUDevice& device)257 {258 auto whlslDescriptor = convertRenderPipelineDescriptor(descriptor);259 if (!whlslDescriptor)260 return false;261 262 auto result = WHLSL::prepare(whlslSource, *whlslDescriptor);263 if (!result)264 return false;265 266 WTFLogAlways("Metal Source: %s", result->metalSource.utf8().data());267 268 NSError *error = nil;269 auto library = adoptNS([device.platformDevice() newLibraryWithSource:result->metalSource options:nil error:&error]);270 ASSERT(library);271 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195771 Once we zero-fill variables, there should be no warnings, so we should be able to ASSERT(!error) here.272 273 return trySetMetalFunctionsForPipelineDescriptor(functionName, library.get(), library.get(), mtlDescriptor, result->mangledVertexEntryPointName, result->mangledFragmentEntryPointName);274 }275 276 static bool trySetFunctionsForPipelineDescriptor(const char* const functionName, MTLRenderPipelineDescriptor *mtlDescriptor, const GPURenderPipelineDescriptor& descriptor, const GPUDevice& device)277 {278 const auto& vertexStage = descriptor.vertexStage;279 const auto& fragmentStage = descriptor.fragmentStage;280 281 const auto& whlslSource = vertexStage.module->whlslSource();282 if (!whlslSource.isNull()) {283 if (!fragmentStage || vertexStage.module.ptr() == fragmentStage->module.ptr()) {284 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195446 Allow WHLSL shaders to come from different programs.285 return trySetWHLSLFunctionsForPipelineDescriptor(functionName, mtlDescriptor, descriptor, whlslSource, device);286 }287 }288 289 auto vertexLibrary = vertexStage.module->platformShaderModule();290 MTLLibrary *fragmentLibrary = nil;291 String fragmentEntryPoint;292 if (fragmentStage) {293 fragmentLibrary = fragmentStage->module->platformShaderModule();294 fragmentEntryPoint = fragmentStage->entryPoint;295 }296 297 return trySetMetalFunctionsForPipelineDescriptor(functionName, vertexLibrary, fragmentLibrary, mtlDescriptor, vertexStage.entryPoint, fragmentEntryPoint);298 }299 300 149 static MTLVertexFormat mtlVertexFormatForGPUVertexFormat(GPUVertexFormat format) 301 150 { … … 326 175 } 327 176 328 static bool trySetInputStateForPipelineDescriptor(const char* const functionName, MTLRenderPipelineDescriptor *mtlDescriptor, const GPUInputStateDescriptor& descriptor) 177 // FIXME: Move this into GPULimits when that is implemented properly. 178 constexpr unsigned maxVertexAttributes = 16; 179 180 static bool trySetVertexInput(const char* const functionName, const GPUVertexInputDescriptor& descriptor, MTLRenderPipelineDescriptor *mtlDescriptor, Optional<WHLSL::RenderPipelineDescriptor>& whlslDescriptor) 329 181 { 330 182 #if LOG_DISABLED 331 183 UNUSED_PARAM(functionName); 332 184 #endif 185 const auto& buffers = descriptor.vertexBuffers; 186 187 if (buffers.size() > maxVertexBuffers) { 188 LOG(WebGPU, "%s: Too many vertex input buffers!", functionName); 189 return false; 190 } 191 333 192 auto mtlVertexDescriptor = adoptNS([MTLVertexDescriptor new]); 334 193 335 const auto& attributes = descriptor.attributes; 336 194 auto layoutArray = retainPtr(mtlVertexDescriptor.get().layouts); 337 195 auto attributeArray = retainPtr(mtlVertexDescriptor.get().attributes); 338 196 339 for (size_t i = 0; i < attributes.size(); ++i) { 340 auto location = static_cast<unsigned>(i); 341 // Maximum number of vertex attributes to be supported by Web GPU. 342 if (location >= 16) { 343 LOG(WebGPU, "%s: Invalid shaderLocation %u for vertex attribute!", functionName, location); 197 // Attribute shaderLocations must be uniquely flat-mapped to [0, {max number of vertex attributes}]. 198 unsigned attributeIndex = 0; 199 HashSet<unsigned, IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> locations; 200 201 for (size_t index = 0; index < buffers.size(); ++index) { 202 if (!buffers[index]) 203 continue; 204 205 const auto& attributes = buffers[index]->attributeSet; 206 207 if (attributes.size() + attributeIndex > maxVertexAttributes) { 208 LOG(WebGPU, "%s: Too many vertex attributes!", functionName); 344 209 return false; 345 210 } 346 if (attributes[i].inputSlot >= maxVertexBuffers) { 347 LOG(WebGPU, "%s: Invalid inputSlot %u for vertex attribute %u!", functionName, attributes[i].inputSlot, location); 211 212 NSUInteger inputStride = 0; 213 if (!WTF::convertSafely(buffers[index]->stride, inputStride)) { 214 LOG(WebGPU, "%s: Stride for vertex input buffer %u is too large!", functionName, index); 348 215 return false; 349 216 } 350 // MTLBuffer size (NSUInteger) is 32 bits on some platforms. 351 // FIXME: Ensure offset < buffer's stride + format's data size. 352 NSUInteger attributeOffset = 0; 353 if (!WTF::convertSafely(attributes[i].offset, attributeOffset)) { 354 LOG(WebGPU, "%s: Buffer offset for vertex attribute %u is too large!", functionName, location); 355 return false; 356 } 357 358 auto mtlAttributeDesc = retainPtr([attributeArray objectAtIndexedSubscript:location]); 359 [mtlAttributeDesc setFormat:mtlVertexFormatForGPUVertexFormat(attributes[i].format)]; 360 [mtlAttributeDesc setOffset:attributeOffset]; 361 [mtlAttributeDesc setBufferIndex:WHLSL::Metal::calculateVertexBufferIndex(attributes[i].inputSlot)]; 362 } 363 364 const auto& inputs = descriptor.inputs; 365 366 auto layoutArray = retainPtr(mtlVertexDescriptor.get().layouts); 367 368 for (size_t j = 0; j < inputs.size(); ++j) { 369 auto slot = inputs[j].inputSlot; 370 if (slot >= maxVertexBuffers) { 371 LOG(WebGPU, "%s: Invalid inputSlot %d for vertex buffer!", functionName, slot); 372 return false; 373 } 374 NSUInteger inputStride = 0; 375 if (!WTF::convertSafely(inputs[j].stride, inputStride)) { 376 LOG(WebGPU, "%s: Stride for vertex buffer slot %d is too large!", functionName, slot); 377 return false; 378 } 379 380 auto convertedSlot = WHLSL::Metal::calculateVertexBufferIndex(slot); 381 auto mtlLayoutDesc = retainPtr([layoutArray objectAtIndexedSubscript:convertedSlot]); 382 [mtlLayoutDesc setStepFunction:mtlStepFunctionForGPUInputStepMode(inputs[j].stepMode)]; 217 218 auto convertedBufferIndex = WHLSL::Metal::calculateVertexBufferIndex(index); 219 220 BEGIN_BLOCK_OBJC_EXCEPTIONS; 221 auto mtlLayoutDesc = retainPtr([layoutArray objectAtIndexedSubscript:convertedBufferIndex]); 222 [mtlLayoutDesc setStepFunction:mtlStepFunctionForGPUInputStepMode(buffers[index]->stepMode)]; 383 223 [mtlLayoutDesc setStride:inputStride]; 224 END_BLOCK_OBJC_EXCEPTIONS; 225 226 for (const auto& attribute : attributes) { 227 if (!locations.add(attribute.shaderLocation).isNewEntry) { 228 LOG(WebGPU, "%s: Duplicate shaderLocation %u for vertex attribute!", functionName, attribute.shaderLocation); 229 return false; 230 } 231 232 NSUInteger offset = 0; 233 if (!WTF::convertSafely(attribute.offset, offset)) { 234 LOG(WebGPU, "%s: Buffer offset for vertex attribute %u is too large!", functionName, attribute.shaderLocation); 235 return false; 236 } 237 238 BEGIN_BLOCK_OBJC_EXCEPTIONS; 239 auto mtlAttributeDesc = retainPtr([attributeArray objectAtIndexedSubscript:attributeIndex]); 240 [mtlAttributeDesc setFormat:mtlVertexFormatForGPUVertexFormat(attribute.format)]; 241 [mtlAttributeDesc setOffset:offset]; 242 [mtlAttributeDesc setBufferIndex:convertedBufferIndex]; 243 END_BLOCK_OBJC_EXCEPTIONS; 244 245 if (whlslDescriptor) 246 whlslDescriptor->vertexAttributes.append({ convertVertexFormat(attribute.format), attribute.shaderLocation, attributeIndex }); 247 248 ++attributeIndex; 249 } 384 250 } 385 251 … … 461 327 } 462 328 463 static void setColorStatesForColorAttachmentArray(MTLRenderPipelineColorAttachmentDescriptorArray* array, const Vector<GPUColorStateDescriptor>& colorStates) 464 { 329 static bool trySetColorStates(const char* const functionName, const Vector<GPUColorStateDescriptor>& colorStates, MTLRenderPipelineColorAttachmentDescriptorArray* array, Optional<WHLSL::RenderPipelineDescriptor>& whlslDescriptor) 330 { 331 #if LOG_DISABLED 332 UNUSED_PARAM(functionName); 333 #endif 334 // FIXME: Replace with maximum number of color attachments per render pass from GPULimits. 335 if (colorStates.size() > 4) { 336 LOG(WebGPU, "%s: Invalid number of GPUColorStateDescriptors!", functionName); 337 return false; 338 } 339 340 BEGIN_BLOCK_OBJC_EXCEPTIONS; 341 465 342 for (unsigned i = 0; i < colorStates.size(); ++i) { 466 343 auto& state = colorStates[i]; … … 475 352 [descriptor setSourceAlphaBlendFactor:mtlBlendFactorForGPUBlendFactor(state.alphaBlend.srcFactor)]; 476 353 [descriptor setSourceRGBBlendFactor:mtlBlendFactorForGPUBlendFactor(state.colorBlend.srcFactor)]; 477 } 478 } 479 480 static RetainPtr<MTLRenderPipelineState> tryCreateMtlRenderPipelineState(const char* const functionName, const GPURenderPipelineDescriptor& descriptor, const GPUDevice& device) 354 355 if (whlslDescriptor) { 356 if (auto format = convertTextureFormat(state.format)) 357 whlslDescriptor->attachmentsStateDescriptor.attachmentDescriptors.append({*format, i}); 358 else { 359 LOG(WebGPU, "%s: Invalid texture format for color attachment %u!", functionName, i); 360 return false; 361 } 362 } 363 } 364 365 END_BLOCK_OBJC_EXCEPTIONS; 366 367 return true; 368 } 369 370 static Optional<WHLSL::Layout> convertLayout(const GPUPipelineLayout& layout) 371 { 372 WHLSL::Layout result; 373 if (layout.bindGroupLayouts().size() > std::numeric_limits<unsigned>::max()) 374 return WTF::nullopt; 375 for (size_t i = 0; i < layout.bindGroupLayouts().size(); ++i) { 376 const auto& bindGroupLayout = layout.bindGroupLayouts()[i]; 377 WHLSL::BindGroup bindGroup; 378 bindGroup.name = static_cast<unsigned>(i); 379 for (const auto& keyValuePair : bindGroupLayout->bindingsMap()) { 380 const auto& gpuBindGroupLayoutBinding = keyValuePair.value; 381 WHLSL::Binding binding; 382 binding.visibility = convertShaderStageFlags(gpuBindGroupLayoutBinding.visibility); 383 if (auto bindingType = convertBindingType(gpuBindGroupLayoutBinding.type)) 384 binding.bindingType = *bindingType; 385 else 386 return WTF::nullopt; 387 if (gpuBindGroupLayoutBinding.binding > std::numeric_limits<unsigned>::max()) 388 return WTF::nullopt; 389 binding.name = static_cast<unsigned>(gpuBindGroupLayoutBinding.binding); 390 bindGroup.bindings.append(WTFMove(binding)); 391 } 392 result.append(WTFMove(bindGroup)); 393 } 394 return result; 395 } 396 397 static bool trySetMetalFunctions(const char* const functionName, MTLLibrary *vertexMetalLibrary, MTLLibrary *fragmentMetalLibrary, MTLRenderPipelineDescriptor *mtlDescriptor, const String& vertexEntryPointName, const String& fragmentEntryPointName) 398 { 399 #if LOG_DISABLED 400 UNUSED_PARAM(functionName); 401 #endif 402 403 { 404 BEGIN_BLOCK_OBJC_EXCEPTIONS; 405 406 // Metal requires a vertex shader in all render pipelines. 407 if (!vertexMetalLibrary) { 408 LOG(WebGPU, "%s: MTLLibrary for vertex stage does not exist!", functionName); 409 return false; 410 } 411 412 auto function = adoptNS([vertexMetalLibrary newFunctionWithName:vertexEntryPointName]); 413 if (!function) { 414 LOG(WebGPU, "%s: Cannot create vertex MTLFunction \"%s\"!", functionName, vertexEntryPointName.utf8().data()); 415 return false; 416 } 417 418 [mtlDescriptor setVertexFunction:function.get()]; 419 420 END_BLOCK_OBJC_EXCEPTIONS; 421 } 422 423 { 424 BEGIN_BLOCK_OBJC_EXCEPTIONS; 425 426 // However, fragment shaders are optional. 427 if (!fragmentMetalLibrary) 428 return true; 429 430 auto function = adoptNS([fragmentMetalLibrary newFunctionWithName:fragmentEntryPointName]); 431 432 if (!function) { 433 LOG(WebGPU, "%s: Cannot create fragment MTLFunction \"%s\"!", functionName, fragmentEntryPointName.utf8().data()); 434 return false; 435 } 436 437 [mtlDescriptor setFragmentFunction:function.get()]; 438 return true; 439 440 END_BLOCK_OBJC_EXCEPTIONS; 441 } 442 443 return false; 444 } 445 446 static bool trySetFunctions(const char* const functionName, const GPUPipelineStageDescriptor& vertexStage, const Optional<GPUPipelineStageDescriptor>& fragmentStage, const GPUDevice& device, MTLRenderPipelineDescriptor* mtlDescriptor, Optional<WHLSL::RenderPipelineDescriptor>& whlslDescriptor) 447 { 448 #if LOG_DISABLED 449 UNUSED_PARAM(functionName); 450 #endif 451 RetainPtr<MTLLibrary> vertexLibrary, fragmentLibrary; 452 String vertexEntryPoint, fragmentEntryPoint; 453 454 if (whlslDescriptor) { 455 // WHLSL functions are compiled to MSL first. 456 String whlslSource = vertexStage.module->whlslSource(); 457 ASSERT(!whlslSource.isNull()); 458 459 whlslDescriptor->vertexEntryPointName = vertexStage.entryPoint; 460 if (fragmentStage) 461 whlslDescriptor->fragmentEntryPointName = fragmentStage->entryPoint; 462 463 auto whlslCompileResult = WHLSL::prepare(whlslSource, *whlslDescriptor); 464 if (!whlslCompileResult) 465 return false; 466 467 WTFLogAlways("Metal Source: %s", whlslCompileResult->metalSource.utf8().data()); 468 469 NSError *error = nil; 470 471 BEGIN_BLOCK_OBJC_EXCEPTIONS; 472 vertexLibrary = adoptNS([device.platformDevice() newLibraryWithSource:whlslCompileResult->metalSource options:nil error:&error]); 473 END_BLOCK_OBJC_EXCEPTIONS; 474 475 ASSERT(vertexLibrary); 476 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195771 Once we zero-fill variables, there should be no warnings, so we should be able to ASSERT(!error) here. 477 478 fragmentLibrary = vertexLibrary; 479 vertexEntryPoint = whlslCompileResult->mangledVertexEntryPointName; 480 fragmentEntryPoint = whlslCompileResult->mangledFragmentEntryPointName; 481 } else { 482 vertexLibrary = vertexStage.module->platformShaderModule(); 483 vertexEntryPoint = vertexStage.entryPoint; 484 if (fragmentStage) { 485 fragmentLibrary = fragmentStage->module->platformShaderModule(); 486 fragmentEntryPoint = fragmentStage->entryPoint; 487 } 488 } 489 490 return trySetMetalFunctions(functionName, vertexLibrary.get(), fragmentLibrary.get(), mtlDescriptor, vertexEntryPoint, fragmentEntryPoint); 491 } 492 493 static RetainPtr<MTLRenderPipelineDescriptor> convertRenderPipelineDescriptor(const char* const functionName, const GPURenderPipelineDescriptor& descriptor, const GPUDevice& device) 481 494 { 482 495 RetainPtr<MTLRenderPipelineDescriptor> mtlDescriptor; … … 493 506 } 494 507 495 bool didSetFunctions = false, didSetInputState = false; 496 497 BEGIN_BLOCK_OBJC_EXCEPTIONS; 498 499 didSetFunctions = trySetFunctionsForPipelineDescriptor(functionName, mtlDescriptor.get(), descriptor, device); 500 didSetInputState = trySetInputStateForPipelineDescriptor(functionName, mtlDescriptor.get(), descriptor.inputState); 501 setColorStatesForColorAttachmentArray(mtlDescriptor.get().colorAttachments, descriptor.colorStates); 502 503 END_BLOCK_OBJC_EXCEPTIONS; 504 505 if (!didSetFunctions || !didSetInputState) 508 // Determine if shader source is in WHLSL or MSL. 509 const auto& vertexStage = descriptor.vertexStage; 510 const auto& fragmentStage = descriptor.fragmentStage; 511 512 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195446 Allow WHLSL shaders to come from different programs. 513 bool isWhlsl = !vertexStage.module->whlslSource().isNull() && (!fragmentStage || vertexStage.module.ptr() == fragmentStage->module.ptr()); 514 515 // Set data for the Metal pipeline descriptor (and WHLSL's, if needed). 516 Optional<WHLSL::RenderPipelineDescriptor> whlslDescriptor; 517 if (isWhlsl) 518 whlslDescriptor = WHLSL::RenderPipelineDescriptor(); 519 520 if (!trySetVertexInput(functionName, descriptor.vertexInput, mtlDescriptor.get(), whlslDescriptor)) 521 return nullptr; 522 523 if (!trySetColorStates(functionName, descriptor.colorStates, mtlDescriptor.get().colorAttachments, whlslDescriptor)) 524 return nullptr; 525 526 if (descriptor.layout && whlslDescriptor) { 527 if (auto layout = convertLayout(*descriptor.layout)) 528 whlslDescriptor->layout = WTFMove(*layout); 529 else { 530 LOG(WebGPU, "%s: Error converting GPUPipelineLayout!", functionName); 531 return nullptr; 532 } 533 } 534 535 if (!trySetFunctions(functionName, vertexStage, fragmentStage, device, mtlDescriptor.get(), whlslDescriptor)) 536 return nullptr; 537 538 return mtlDescriptor; 539 } 540 541 static RetainPtr<MTLRenderPipelineState> tryCreateMtlRenderPipelineState(const char* const functionName, const GPURenderPipelineDescriptor& descriptor, const GPUDevice& device) 542 { 543 auto mtlDescriptor = convertRenderPipelineDescriptor(functionName, descriptor, device); 544 if (!mtlDescriptor) 506 545 return nullptr; 507 546 … … 534 573 return nullptr; 535 574 575 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198387 depthStencilAttachmentDescriptor isn't implemented yet for WHLSL compiler. 576 536 577 auto pipeline = tryCreateMtlRenderPipelineState(functionName, descriptor, device); 537 578 if (!pipeline) 538 579 return nullptr; 539 580 540 return adoptRef(new GPURenderPipeline(WTFMove(depthStencil), WTFMove(pipeline), descriptor.primitiveTopology, descriptor. inputState.indexFormat));581 return adoptRef(new GPURenderPipeline(WTFMove(depthStencil), WTFMove(pipeline), descriptor.primitiveTopology, descriptor.vertexInput.indexFormat)); 541 582 } 542 583
Note: See TracChangeset
for help on using the changeset viewer.