diff options
Diffstat (limited to 'chromium/third_party/angle/src/libANGLE/renderer/metal/mtl_render_utils.mm')
-rw-r--r-- | chromium/third_party/angle/src/libANGLE/renderer/metal/mtl_render_utils.mm | 156 |
1 files changed, 131 insertions, 25 deletions
diff --git a/chromium/third_party/angle/src/libANGLE/renderer/metal/mtl_render_utils.mm b/chromium/third_party/angle/src/libANGLE/renderer/metal/mtl_render_utils.mm index 54bd0526a7c..94bc3dde74c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/metal/mtl_render_utils.mm +++ b/chromium/third_party/angle/src/libANGLE/renderer/metal/mtl_render_utils.mm @@ -25,10 +25,14 @@ namespace mtl namespace { +#define NUM_COLOR_OUTPUTS_CONSTANT_NAME @"kNumColorOutputs" #define SOURCE_BUFFER_ALIGNED_CONSTANT_NAME @"kSourceBufferAligned" #define SOURCE_IDX_IS_U8_CONSTANT_NAME @"kSourceIndexIsU8" #define SOURCE_IDX_IS_U16_CONSTANT_NAME @"kSourceIndexIsU16" #define SOURCE_IDX_IS_U32_CONSTANT_NAME @"kSourceIndexIsU32" +#define PREMULTIPLY_ALPHA_CONSTANT_NAME @"kPremultiplyAlpha" +#define UNMULTIPLY_ALPHA_CONSTANT_NAME @"kUnmultiplyAlpha" +#define SOURCE_TEXTURE_TYPE_CONSTANT_NAME @"kSourceTextureType" // See libANGLE/renderer/metal/shaders/clear.metal struct ClearParamsUniform @@ -44,10 +48,12 @@ struct BlitParamsUniform // 0: lower left, 1: lower right, 2: upper left float srcTexCoords[3][2]; int srcLevel = 0; - uint8_t srcLuminance = 0; // source texture is luminance texture + int srcLayer = 0; + uint8_t dstFlipX = 0; uint8_t dstFlipY = 0; uint8_t dstLuminance = 0; // dest texture is luminace - uint8_t padding; + uint8_t padding1; + float padding2[3]; }; struct IndexConversionUniform @@ -131,6 +137,31 @@ void GetFirstLastIndicesFromClientElements(GLsizei count, memcpy(lastOut, indices + count - 1, sizeof(indices[0])); } +int GetShaderTextureType(const TextureRef &texture) +{ + if (!texture) + { + return -1; + } + switch (texture->textureType()) + { + case MTLTextureType2D: + return mtl_shader::kTextureType2D; + case MTLTextureType2DArray: + return mtl_shader::kTextureType2DArray; + case MTLTextureType2DMultisample: + return mtl_shader::kTextureType2DMultisample; + case MTLTextureTypeCube: + return mtl_shader::kTextureTypeCube; + case MTLTextureType3D: + return mtl_shader::kTextureType3D; + default: + UNREACHABLE(); + } + + return 0; +} + ANGLE_INLINE void EnsureComputePipelineInitialized(DisplayMtl *display, NSString *functionName, @@ -208,6 +239,15 @@ void EnsureSpecializedComputePipelineInitialized( } template <typename T> +void ClearRenderPipelineCacheArray(T *pipelineCacheArray) +{ + for (RenderPipelineCache &pipelineCache : *pipelineCacheArray) + { + pipelineCache.clear(); + } +} + +template <typename T> void ClearPipelineStateArray(T *pipelineCacheArray) { for (auto &pipeline : *pipelineCacheArray) @@ -353,6 +393,20 @@ angle::Result RenderUtils::blitWithDraw(const gl::Context *context, return mColorBlitUtils.blitWithDraw(context, cmdEncoder, params); } +angle::Result RenderUtils::blitWithDraw(const gl::Context *context, + RenderCommandEncoder *cmdEncoder, + const TextureRef &srcTexture) +{ + if (!srcTexture) + { + return angle::Result::Continue; + } + BlitParams params; + params.src = srcTexture; + params.srcRect = gl::Rectangle(0, 0, srcTexture->width(), srcTexture->height()); + return blitWithDraw(context, cmdEncoder, params); +} + angle::Result RenderUtils::convertIndexBufferGPU(ContextMtl *contextMtl, const IndexConversionParams ¶ms) { @@ -398,12 +452,26 @@ void ClearUtils::ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx) { ANGLE_MTL_OBJC_SCOPE { + NSError *err = nil; id<MTLLibrary> shaderLib = ctx->getDisplay()->getDefaultShadersLib(); + id<MTLFunction> vertexShader = + [[shaderLib newFunctionWithName:@"clearVS"] ANGLE_MTL_AUTORELEASE]; + MTLFunctionConstantValues *funcConstants = + [[[MTLFunctionConstantValues alloc] init] ANGLE_MTL_AUTORELEASE]; + + // Use 1 color outputs for now. + uint32_t numOutputs = 1; + [funcConstants setConstantValue:&numOutputs + type:MTLDataTypeUInt + withName:NUM_COLOR_OUTPUTS_CONSTANT_NAME]; + + id<MTLFunction> fragmentShader = + [[shaderLib newFunctionWithName:@"clearFS" constantValues:funcConstants + error:&err] ANGLE_MTL_AUTORELEASE]; + ASSERT(fragmentShader); - mClearRenderPipelineCache.setVertexShader( - ctx, [[shaderLib newFunctionWithName:@"clearVS"] ANGLE_MTL_AUTORELEASE]); - mClearRenderPipelineCache.setFragmentShader( - ctx, [[shaderLib newFunctionWithName:@"clearFS"] ANGLE_MTL_AUTORELEASE]); + mClearRenderPipelineCache.setVertexShader(ctx, vertexShader); + mClearRenderPipelineCache.setFragmentShader(ctx, fragmentShader); } } @@ -570,13 +638,14 @@ ColorBlitUtils::ColorBlitUtils() = default; void ColorBlitUtils::onDestroy() { - mBlitRenderPipelineCache.clear(); - mBlitPremultiplyAlphaRenderPipelineCache.clear(); - mBlitUnmultiplyAlphaRenderPipelineCache.clear(); + ClearRenderPipelineCacheArray(&mBlitRenderPipelineCache); + ClearRenderPipelineCacheArray(&mBlitPremultiplyAlphaRenderPipelineCache); + ClearRenderPipelineCacheArray(&mBlitUnmultiplyAlphaRenderPipelineCache); } void ColorBlitUtils::ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx, int alphaPremultiplyType, + int textureType, RenderPipelineCache *cacheOut) { RenderPipelineCache &pipelineCache = *cacheOut; @@ -588,24 +657,49 @@ void ColorBlitUtils::ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx, ANGLE_MTL_OBJC_SCOPE { - NSString *const fragmentShaderNames[] = {// Normal blit - @"blitFS", - // Blit premultiply-alpha - @"blitPremultiplyAlphaFS", - // Blit unmultiply alpha - @"blitUnmultiplyAlphaFS"}; - + NSError *err = nil; id<MTLLibrary> shaderLib = ctx->getDisplay()->getDefaultShadersLib(); id<MTLFunction> vertexShader = [[shaderLib newFunctionWithName:@"blitVS"] ANGLE_MTL_AUTORELEASE]; - id<MTLFunction> fragmentShader = [[shaderLib - newFunctionWithName:fragmentShaderNames[alphaPremultiplyType]] ANGLE_MTL_AUTORELEASE]; + MTLFunctionConstantValues *funcConstants = + [[[MTLFunctionConstantValues alloc] init] ANGLE_MTL_AUTORELEASE]; + + constexpr BOOL multiplyAlphaFlags[][2] = {// premultiply, unmultiply + + // Normal blit + {NO, NO}, + // Blit premultiply-alpha + {YES, NO}, + // Blit unmultiply alpha + {NO, YES}}; + + // Set alpha multiply flags + [funcConstants setConstantValue:&multiplyAlphaFlags[alphaPremultiplyType][0] + type:MTLDataTypeBool + withName:PREMULTIPLY_ALPHA_CONSTANT_NAME]; + [funcConstants setConstantValue:&multiplyAlphaFlags[alphaPremultiplyType][1] + type:MTLDataTypeBool + withName:UNMULTIPLY_ALPHA_CONSTANT_NAME]; + + // Use 1 color outputs for now. + uint32_t numOutputs = 1; + [funcConstants setConstantValue:&numOutputs + type:MTLDataTypeUInt + withName:NUM_COLOR_OUTPUTS_CONSTANT_NAME]; + + // Set texture type constant + [funcConstants setConstantValue:&textureType + type:MTLDataTypeInt + withName:SOURCE_TEXTURE_TYPE_CONSTANT_NAME]; + + id<MTLFunction> fragmentShader = + [[shaderLib newFunctionWithName:@"blitFS" constantValues:funcConstants + error:&err] ANGLE_MTL_AUTORELEASE]; ASSERT(vertexShader); ASSERT(fragmentShader); - - mBlitRenderPipelineCache.setVertexShader(ctx, vertexShader); - mBlitRenderPipelineCache.setFragmentShader(ctx, fragmentShader); + pipelineCache.setVertexShader(ctx, vertexShader); + pipelineCache.setFragmentShader(ctx, fragmentShader); } } @@ -625,23 +719,25 @@ id<MTLRenderPipelineState> ColorBlitUtils::getBlitRenderPipelineState( RenderPipelineCache *pipelineCache; int alphaPremultiplyType; + int textureType = GetShaderTextureType(params.src); if (params.unpackPremultiplyAlpha == params.unpackUnmultiplyAlpha) { alphaPremultiplyType = 0; - pipelineCache = &mBlitRenderPipelineCache; + pipelineCache = &mBlitRenderPipelineCache[textureType]; } else if (params.unpackPremultiplyAlpha) { alphaPremultiplyType = 1; - pipelineCache = &mBlitPremultiplyAlphaRenderPipelineCache; + pipelineCache = &mBlitPremultiplyAlphaRenderPipelineCache[textureType]; } else { alphaPremultiplyType = 2; - pipelineCache = &mBlitUnmultiplyAlphaRenderPipelineCache; + pipelineCache = &mBlitUnmultiplyAlphaRenderPipelineCache[textureType]; } - ensureRenderPipelineStateCacheInitialized(contextMtl, alphaPremultiplyType, pipelineCache); + ensureRenderPipelineStateCacheInitialized(contextMtl, alphaPremultiplyType, textureType, + pipelineCache); return pipelineCache->getRenderPipelineState(contextMtl, pipelineDesc); } @@ -681,6 +777,16 @@ void ColorBlitUtils::setupBlitWithDraw(const gl::Context *context, cmdEncoder->setFragmentTexture(params.src, 0); + // Set default sampler state with linear filtering. + // NOTE(hqle): Support configurable filtering (required by glBitFramebuffer). + SamplerDesc samplerDesc; + samplerDesc.reset(); + samplerDesc.minFilter = samplerDesc.magFilter = MTLSamplerMinMagFilterLinear; + + cmdEncoder->setFragmentSamplerState(contextMtl->getDisplay()->getStateCache().getSamplerState( + contextMtl->getMetalDevice(), samplerDesc), + 0, FLT_MAX, 0); + // Uniform SetupBlitWithDrawUniformData(cmdEncoder, params); } |