1*8975f5c5SAndroid Build Coastguard Worker// 2*8975f5c5SAndroid Build Coastguard Worker// Copyright 2021 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker// found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker// 6*8975f5c5SAndroid Build Coastguard Worker// ProvokingVertexHelper.mm: 7*8975f5c5SAndroid Build Coastguard Worker// Implements the class methods for ProvokingVertexHelper. 8*8975f5c5SAndroid Build Coastguard Worker// 9*8975f5c5SAndroid Build Coastguard Worker 10*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/ProvokingVertexHelper.h" 11*8975f5c5SAndroid Build Coastguard Worker#import <Foundation/Foundation.h> 12*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/Display.h" 13*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/ContextMtl.h" 14*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/DisplayMtl.h" 15*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/mtl_common.h" 16*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/shaders/rewrite_indices_shared.h" 17*8975f5c5SAndroid Build Coastguard Workernamespace rx 18*8975f5c5SAndroid Build Coastguard Worker{ 19*8975f5c5SAndroid Build Coastguard Worker 20*8975f5c5SAndroid Build Coastguard Workernamespace 21*8975f5c5SAndroid Build Coastguard Worker{ 22*8975f5c5SAndroid Build Coastguard Workerconstexpr size_t kInitialIndexBufferSize = 0xFFFF; // Initial 64k pool. 23*8975f5c5SAndroid Build Coastguard Worker} 24*8975f5c5SAndroid Build Coastguard Workerstatic inline uint primCountForIndexCount(const uint fixIndexBufferKey, const uint indexCount) 25*8975f5c5SAndroid Build Coastguard Worker{ 26*8975f5c5SAndroid Build Coastguard Worker const uint fixIndexBufferMode = 27*8975f5c5SAndroid Build Coastguard Worker (fixIndexBufferKey >> MtlFixIndexBufferKeyModeShift) & MtlFixIndexBufferKeyModeMask; 28*8975f5c5SAndroid Build Coastguard Worker 29*8975f5c5SAndroid Build Coastguard Worker switch (fixIndexBufferMode) 30*8975f5c5SAndroid Build Coastguard Worker { 31*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyPoints: 32*8975f5c5SAndroid Build Coastguard Worker return indexCount; 33*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyLines: 34*8975f5c5SAndroid Build Coastguard Worker return indexCount / 2; 35*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyLineStrip: 36*8975f5c5SAndroid Build Coastguard Worker return (uint)MAX(0, (int)indexCount - 1); 37*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyLineLoop: 38*8975f5c5SAndroid Build Coastguard Worker return (uint)MAX(0, (int)indexCount); 39*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyTriangles: 40*8975f5c5SAndroid Build Coastguard Worker return indexCount / 3; 41*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyTriangleStrip: 42*8975f5c5SAndroid Build Coastguard Worker return (uint)MAX(0, (int)indexCount - 2); 43*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyTriangleFan: 44*8975f5c5SAndroid Build Coastguard Worker return (uint)MAX(0, (int)indexCount - 2); 45*8975f5c5SAndroid Build Coastguard Worker default: 46*8975f5c5SAndroid Build Coastguard Worker ASSERT(false); 47*8975f5c5SAndroid Build Coastguard Worker return 0; 48*8975f5c5SAndroid Build Coastguard Worker } 49*8975f5c5SAndroid Build Coastguard Worker} 50*8975f5c5SAndroid Build Coastguard Worker 51*8975f5c5SAndroid Build Coastguard Workerstatic inline uint indexCountForPrimCount(const uint fixIndexBufferKey, const uint primCount) 52*8975f5c5SAndroid Build Coastguard Worker{ 53*8975f5c5SAndroid Build Coastguard Worker const uint fixIndexBufferMode = 54*8975f5c5SAndroid Build Coastguard Worker (fixIndexBufferKey >> MtlFixIndexBufferKeyModeShift) & MtlFixIndexBufferKeyModeMask; 55*8975f5c5SAndroid Build Coastguard Worker switch (fixIndexBufferMode) 56*8975f5c5SAndroid Build Coastguard Worker { 57*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyPoints: 58*8975f5c5SAndroid Build Coastguard Worker return primCount; 59*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyLines: 60*8975f5c5SAndroid Build Coastguard Worker return primCount * 2; 61*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyLineStrip: 62*8975f5c5SAndroid Build Coastguard Worker return primCount * 2; 63*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyLineLoop: 64*8975f5c5SAndroid Build Coastguard Worker return primCount * 2; 65*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyTriangles: 66*8975f5c5SAndroid Build Coastguard Worker return primCount * 3; 67*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyTriangleStrip: 68*8975f5c5SAndroid Build Coastguard Worker return primCount * 3; 69*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyTriangleFan: 70*8975f5c5SAndroid Build Coastguard Worker return primCount * 3; 71*8975f5c5SAndroid Build Coastguard Worker default: 72*8975f5c5SAndroid Build Coastguard Worker ASSERT(false); 73*8975f5c5SAndroid Build Coastguard Worker return 0; 74*8975f5c5SAndroid Build Coastguard Worker } 75*8975f5c5SAndroid Build Coastguard Worker} 76*8975f5c5SAndroid Build Coastguard Worker 77*8975f5c5SAndroid Build Coastguard Workerstatic inline gl::PrimitiveMode getNewPrimitiveMode(const uint fixIndexBufferKey) 78*8975f5c5SAndroid Build Coastguard Worker{ 79*8975f5c5SAndroid Build Coastguard Worker const uint fixIndexBufferMode = 80*8975f5c5SAndroid Build Coastguard Worker (fixIndexBufferKey >> MtlFixIndexBufferKeyModeShift) & MtlFixIndexBufferKeyModeMask; 81*8975f5c5SAndroid Build Coastguard Worker switch (fixIndexBufferMode) 82*8975f5c5SAndroid Build Coastguard Worker { 83*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyPoints: 84*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::Points; 85*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyLines: 86*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::Lines; 87*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyLineStrip: 88*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::Lines; 89*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyLineLoop: 90*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::Lines; 91*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyTriangles: 92*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::Triangles; 93*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyTriangleStrip: 94*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::Triangles; 95*8975f5c5SAndroid Build Coastguard Worker case MtlFixIndexBufferKeyTriangleFan: 96*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::Triangles; 97*8975f5c5SAndroid Build Coastguard Worker default: 98*8975f5c5SAndroid Build Coastguard Worker ASSERT(false); 99*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::InvalidEnum; 100*8975f5c5SAndroid Build Coastguard Worker } 101*8975f5c5SAndroid Build Coastguard Worker} 102*8975f5c5SAndroid Build Coastguard WorkerProvokingVertexHelper::ProvokingVertexHelper(ContextMtl *context) : mIndexBuffers(false) 103*8975f5c5SAndroid Build Coastguard Worker{ 104*8975f5c5SAndroid Build Coastguard Worker mIndexBuffers.initialize(context, kInitialIndexBufferSize, mtl::kIndexBufferOffsetAlignment, 0); 105*8975f5c5SAndroid Build Coastguard Worker} 106*8975f5c5SAndroid Build Coastguard Worker 107*8975f5c5SAndroid Build Coastguard Workervoid ProvokingVertexHelper::onDestroy(ContextMtl *context) 108*8975f5c5SAndroid Build Coastguard Worker{ 109*8975f5c5SAndroid Build Coastguard Worker mIndexBuffers.destroy(context); 110*8975f5c5SAndroid Build Coastguard Worker} 111*8975f5c5SAndroid Build Coastguard Worker 112*8975f5c5SAndroid Build Coastguard Workervoid ProvokingVertexHelper::releaseInFlightBuffers(ContextMtl *contextMtl) 113*8975f5c5SAndroid Build Coastguard Worker{ 114*8975f5c5SAndroid Build Coastguard Worker mIndexBuffers.releaseInFlightBuffers(contextMtl); 115*8975f5c5SAndroid Build Coastguard Worker} 116*8975f5c5SAndroid Build Coastguard Worker 117*8975f5c5SAndroid Build Coastguard Workerstatic uint buildIndexBufferKey(const mtl::ProvokingVertexComputePipelineDesc &pipelineDesc) 118*8975f5c5SAndroid Build Coastguard Worker{ 119*8975f5c5SAndroid Build Coastguard Worker uint indexBufferKey = 0; 120*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType elementType = (gl::DrawElementsType)pipelineDesc.elementType; 121*8975f5c5SAndroid Build Coastguard Worker bool doPrimPrestart = pipelineDesc.primitiveRestartEnabled; 122*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode primMode = pipelineDesc.primitiveMode; 123*8975f5c5SAndroid Build Coastguard Worker switch (elementType) 124*8975f5c5SAndroid Build Coastguard Worker { 125*8975f5c5SAndroid Build Coastguard Worker case gl::DrawElementsType::UnsignedShort: 126*8975f5c5SAndroid Build Coastguard Worker indexBufferKey |= MtlFixIndexBufferKeyUint16 << MtlFixIndexBufferKeyInShift; 127*8975f5c5SAndroid Build Coastguard Worker indexBufferKey |= MtlFixIndexBufferKeyUint16 << MtlFixIndexBufferKeyOutShift; 128*8975f5c5SAndroid Build Coastguard Worker break; 129*8975f5c5SAndroid Build Coastguard Worker case gl::DrawElementsType::UnsignedInt: 130*8975f5c5SAndroid Build Coastguard Worker indexBufferKey |= MtlFixIndexBufferKeyUint32 << MtlFixIndexBufferKeyInShift; 131*8975f5c5SAndroid Build Coastguard Worker indexBufferKey |= MtlFixIndexBufferKeyUint32 << MtlFixIndexBufferKeyOutShift; 132*8975f5c5SAndroid Build Coastguard Worker break; 133*8975f5c5SAndroid Build Coastguard Worker default: 134*8975f5c5SAndroid Build Coastguard Worker ASSERT(false); // Index type should only be short or int. 135*8975f5c5SAndroid Build Coastguard Worker break; 136*8975f5c5SAndroid Build Coastguard Worker } 137*8975f5c5SAndroid Build Coastguard Worker indexBufferKey |= (uint)primMode << MtlFixIndexBufferKeyModeShift; 138*8975f5c5SAndroid Build Coastguard Worker indexBufferKey |= doPrimPrestart ? MtlFixIndexBufferKeyPrimRestart : 0; 139*8975f5c5SAndroid Build Coastguard Worker // We only rewrite indices if we're switching the provoking vertex mode. 140*8975f5c5SAndroid Build Coastguard Worker indexBufferKey |= MtlFixIndexBufferKeyProvokingVertexLast; 141*8975f5c5SAndroid Build Coastguard Worker return indexBufferKey; 142*8975f5c5SAndroid Build Coastguard Worker} 143*8975f5c5SAndroid Build Coastguard Worker 144*8975f5c5SAndroid Build Coastguard Workerangle::Result ProvokingVertexHelper::getComputePipleineState( 145*8975f5c5SAndroid Build Coastguard Worker ContextMtl *context, 146*8975f5c5SAndroid Build Coastguard Worker const mtl::ProvokingVertexComputePipelineDesc &desc, 147*8975f5c5SAndroid Build Coastguard Worker mtl::AutoObjCPtr<id<MTLComputePipelineState>> *outComputePipeline) 148*8975f5c5SAndroid Build Coastguard Worker{ 149*8975f5c5SAndroid Build Coastguard Worker auto iter = mComputeFunctions.find(desc); 150*8975f5c5SAndroid Build Coastguard Worker if (iter != mComputeFunctions.end()) 151*8975f5c5SAndroid Build Coastguard Worker { 152*8975f5c5SAndroid Build Coastguard Worker return context->getPipelineCache().getComputePipeline(context, iter->second, 153*8975f5c5SAndroid Build Coastguard Worker outComputePipeline); 154*8975f5c5SAndroid Build Coastguard Worker } 155*8975f5c5SAndroid Build Coastguard Worker 156*8975f5c5SAndroid Build Coastguard Worker id<MTLLibrary> provokingVertexLibrary = context->getDisplay()->getDefaultShadersLib(); 157*8975f5c5SAndroid Build Coastguard Worker uint indexBufferKey = buildIndexBufferKey(desc); 158*8975f5c5SAndroid Build Coastguard Worker auto fcValues = mtl::adoptObjCObj([[MTLFunctionConstantValues alloc] init]); 159*8975f5c5SAndroid Build Coastguard Worker [fcValues setConstantValue:&indexBufferKey type:MTLDataTypeUInt withName:@"fixIndexBufferKey"]; 160*8975f5c5SAndroid Build Coastguard Worker 161*8975f5c5SAndroid Build Coastguard Worker mtl::AutoObjCPtr<id<MTLFunction>> computeShader; 162*8975f5c5SAndroid Build Coastguard Worker if (desc.generateIndices) 163*8975f5c5SAndroid Build Coastguard Worker { 164*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(CreateMslShader(context, provokingVertexLibrary, @"genIndexBuffer", 165*8975f5c5SAndroid Build Coastguard Worker fcValues.get(), &computeShader)); 166*8975f5c5SAndroid Build Coastguard Worker } 167*8975f5c5SAndroid Build Coastguard Worker else 168*8975f5c5SAndroid Build Coastguard Worker { 169*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(CreateMslShader(context, provokingVertexLibrary, @"fixIndexBuffer", 170*8975f5c5SAndroid Build Coastguard Worker fcValues.get(), &computeShader)); 171*8975f5c5SAndroid Build Coastguard Worker } 172*8975f5c5SAndroid Build Coastguard Worker mComputeFunctions[desc] = computeShader; 173*8975f5c5SAndroid Build Coastguard Worker 174*8975f5c5SAndroid Build Coastguard Worker return context->getPipelineCache().getComputePipeline(context, computeShader, 175*8975f5c5SAndroid Build Coastguard Worker outComputePipeline); 176*8975f5c5SAndroid Build Coastguard Worker} 177*8975f5c5SAndroid Build Coastguard Worker 178*8975f5c5SAndroid Build Coastguard Workerangle::Result ProvokingVertexHelper::prepareCommandEncoderForDescriptor( 179*8975f5c5SAndroid Build Coastguard Worker ContextMtl *context, 180*8975f5c5SAndroid Build Coastguard Worker mtl::ComputeCommandEncoder *encoder, 181*8975f5c5SAndroid Build Coastguard Worker mtl::ProvokingVertexComputePipelineDesc desc) 182*8975f5c5SAndroid Build Coastguard Worker{ 183*8975f5c5SAndroid Build Coastguard Worker mtl::AutoObjCPtr<id<MTLComputePipelineState>> pipelineState; 184*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getComputePipleineState(context, desc, &pipelineState)); 185*8975f5c5SAndroid Build Coastguard Worker 186*8975f5c5SAndroid Build Coastguard Worker encoder->setComputePipelineState(pipelineState); 187*8975f5c5SAndroid Build Coastguard Worker 188*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue; 189*8975f5c5SAndroid Build Coastguard Worker} 190*8975f5c5SAndroid Build Coastguard Worker 191*8975f5c5SAndroid Build Coastguard Workerangle::Result ProvokingVertexHelper::preconditionIndexBuffer(ContextMtl *context, 192*8975f5c5SAndroid Build Coastguard Worker mtl::BufferRef indexBuffer, 193*8975f5c5SAndroid Build Coastguard Worker size_t indexCount, 194*8975f5c5SAndroid Build Coastguard Worker size_t indexOffset, 195*8975f5c5SAndroid Build Coastguard Worker bool primitiveRestartEnabled, 196*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode primitiveMode, 197*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType elementsType, 198*8975f5c5SAndroid Build Coastguard Worker size_t &outIndexCount, 199*8975f5c5SAndroid Build Coastguard Worker size_t &outIndexOffset, 200*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode &outPrimitiveMode, 201*8975f5c5SAndroid Build Coastguard Worker mtl::BufferRef &outNewBuffer) 202*8975f5c5SAndroid Build Coastguard Worker{ 203*8975f5c5SAndroid Build Coastguard Worker // Get specialized program 204*8975f5c5SAndroid Build Coastguard Worker // Upload index buffer 205*8975f5c5SAndroid Build Coastguard Worker // dispatch per-primitive? 206*8975f5c5SAndroid Build Coastguard Worker mtl::ProvokingVertexComputePipelineDesc pipelineDesc; 207*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.elementType = (uint8_t)elementsType; 208*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.primitiveMode = primitiveMode; 209*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.primitiveRestartEnabled = primitiveRestartEnabled; 210*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.generateIndices = false; 211*8975f5c5SAndroid Build Coastguard Worker uint indexBufferKey = buildIndexBufferKey(pipelineDesc); 212*8975f5c5SAndroid Build Coastguard Worker uint primCount = primCountForIndexCount(indexBufferKey, (uint32_t)indexCount); 213*8975f5c5SAndroid Build Coastguard Worker uint newIndexCount = indexCountForPrimCount(indexBufferKey, primCount); 214*8975f5c5SAndroid Build Coastguard Worker size_t indexSize = gl::GetDrawElementsTypeSize(elementsType); 215*8975f5c5SAndroid Build Coastguard Worker size_t newOffset = 0; 216*8975f5c5SAndroid Build Coastguard Worker mtl::BufferRef newBuffer; 217*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mIndexBuffers.allocate(context, newIndexCount * indexSize + indexOffset, nullptr, 218*8975f5c5SAndroid Build Coastguard Worker &newBuffer, &newOffset)); 219*8975f5c5SAndroid Build Coastguard Worker uint indexCountEncoded = (uint)indexCount; 220*8975f5c5SAndroid Build Coastguard Worker auto threadsPerThreadgroup = MTLSizeMake(MIN(primCount, 64u), 1, 1); 221*8975f5c5SAndroid Build Coastguard Worker 222*8975f5c5SAndroid Build Coastguard Worker mtl::ComputeCommandEncoder *encoder = 223*8975f5c5SAndroid Build Coastguard Worker context->getComputeCommandEncoderWithoutEndingRenderEncoder(); 224*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(prepareCommandEncoderForDescriptor(context, encoder, pipelineDesc)); 225*8975f5c5SAndroid Build Coastguard Worker encoder->setBuffer(indexBuffer, static_cast<uint32_t>(indexOffset), 0); 226*8975f5c5SAndroid Build Coastguard Worker encoder->setBufferForWrite( 227*8975f5c5SAndroid Build Coastguard Worker newBuffer, static_cast<uint32_t>(indexOffset) + static_cast<uint32_t>(newOffset), 1); 228*8975f5c5SAndroid Build Coastguard Worker encoder->setData(&indexCountEncoded, 2); 229*8975f5c5SAndroid Build Coastguard Worker encoder->setData(&primCount, 3); 230*8975f5c5SAndroid Build Coastguard Worker encoder->dispatch( 231*8975f5c5SAndroid Build Coastguard Worker MTLSizeMake((primCount + threadsPerThreadgroup.width - 1) / threadsPerThreadgroup.width, 1, 232*8975f5c5SAndroid Build Coastguard Worker 1), 233*8975f5c5SAndroid Build Coastguard Worker threadsPerThreadgroup); 234*8975f5c5SAndroid Build Coastguard Worker outIndexCount = newIndexCount; 235*8975f5c5SAndroid Build Coastguard Worker outIndexOffset = newOffset; 236*8975f5c5SAndroid Build Coastguard Worker outPrimitiveMode = getNewPrimitiveMode(indexBufferKey); 237*8975f5c5SAndroid Build Coastguard Worker outNewBuffer = newBuffer; 238*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue; 239*8975f5c5SAndroid Build Coastguard Worker} 240*8975f5c5SAndroid Build Coastguard Worker 241*8975f5c5SAndroid Build Coastguard Workerangle::Result ProvokingVertexHelper::generateIndexBuffer(ContextMtl *context, 242*8975f5c5SAndroid Build Coastguard Worker size_t first, 243*8975f5c5SAndroid Build Coastguard Worker size_t indexCount, 244*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode primitiveMode, 245*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType elementsType, 246*8975f5c5SAndroid Build Coastguard Worker size_t &outIndexCount, 247*8975f5c5SAndroid Build Coastguard Worker size_t &outIndexOffset, 248*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode &outPrimitiveMode, 249*8975f5c5SAndroid Build Coastguard Worker mtl::BufferRef &outNewBuffer) 250*8975f5c5SAndroid Build Coastguard Worker{ 251*8975f5c5SAndroid Build Coastguard Worker // Get specialized program 252*8975f5c5SAndroid Build Coastguard Worker // Upload index buffer 253*8975f5c5SAndroid Build Coastguard Worker // dispatch per-primitive? 254*8975f5c5SAndroid Build Coastguard Worker mtl::ProvokingVertexComputePipelineDesc pipelineDesc; 255*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.elementType = (uint8_t)elementsType; 256*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.primitiveMode = primitiveMode; 257*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.primitiveRestartEnabled = false; 258*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.generateIndices = true; 259*8975f5c5SAndroid Build Coastguard Worker uint indexBufferKey = buildIndexBufferKey(pipelineDesc); 260*8975f5c5SAndroid Build Coastguard Worker uint primCount = primCountForIndexCount(indexBufferKey, (uint32_t)indexCount); 261*8975f5c5SAndroid Build Coastguard Worker uint newIndexCount = indexCountForPrimCount(indexBufferKey, primCount); 262*8975f5c5SAndroid Build Coastguard Worker size_t indexSize = gl::GetDrawElementsTypeSize(elementsType); 263*8975f5c5SAndroid Build Coastguard Worker size_t newIndexOffset = 0; 264*8975f5c5SAndroid Build Coastguard Worker mtl::BufferRef newBuffer; 265*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mIndexBuffers.allocate(context, newIndexCount * indexSize, nullptr, &newBuffer, 266*8975f5c5SAndroid Build Coastguard Worker &newIndexOffset)); 267*8975f5c5SAndroid Build Coastguard Worker uint indexCountEncoded = static_cast<uint>(indexCount); 268*8975f5c5SAndroid Build Coastguard Worker uint firstVertexEncoded = static_cast<uint>(first); 269*8975f5c5SAndroid Build Coastguard Worker uint indexOffsetEncoded = static_cast<uint>(newIndexOffset); 270*8975f5c5SAndroid Build Coastguard Worker auto threadsPerThreadgroup = MTLSizeMake(MIN(primCount, 64u), 1, 1); 271*8975f5c5SAndroid Build Coastguard Worker 272*8975f5c5SAndroid Build Coastguard Worker mtl::ComputeCommandEncoder *encoder = 273*8975f5c5SAndroid Build Coastguard Worker context->getComputeCommandEncoderWithoutEndingRenderEncoder(); 274*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(prepareCommandEncoderForDescriptor(context, encoder, pipelineDesc)); 275*8975f5c5SAndroid Build Coastguard Worker encoder->setBufferForWrite(newBuffer, indexOffsetEncoded, 1); 276*8975f5c5SAndroid Build Coastguard Worker encoder->setData(indexCountEncoded, 2); 277*8975f5c5SAndroid Build Coastguard Worker encoder->setData(primCount, 3); 278*8975f5c5SAndroid Build Coastguard Worker encoder->setData(firstVertexEncoded, 4); 279*8975f5c5SAndroid Build Coastguard Worker encoder->dispatch( 280*8975f5c5SAndroid Build Coastguard Worker MTLSizeMake((primCount + threadsPerThreadgroup.width - 1) / threadsPerThreadgroup.width, 1, 281*8975f5c5SAndroid Build Coastguard Worker 1), 282*8975f5c5SAndroid Build Coastguard Worker threadsPerThreadgroup); 283*8975f5c5SAndroid Build Coastguard Worker outIndexCount = newIndexCount; 284*8975f5c5SAndroid Build Coastguard Worker outIndexOffset = newIndexOffset; 285*8975f5c5SAndroid Build Coastguard Worker outPrimitiveMode = getNewPrimitiveMode(indexBufferKey); 286*8975f5c5SAndroid Build Coastguard Worker outNewBuffer = newBuffer; 287*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue; 288*8975f5c5SAndroid Build Coastguard Worker} 289*8975f5c5SAndroid Build Coastguard Worker 290*8975f5c5SAndroid Build Coastguard Worker} // namespace rx 291