1 // 2 // Copyright 2016 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // ShaderVk.cpp: 7 // Implements the class methods for ShaderVk. 8 // 9 10 #include "libANGLE/renderer/vulkan/ShaderVk.h" 11 12 #include "common/debug.h" 13 #include "libANGLE/Context.h" 14 #include "libANGLE/Display.h" 15 #include "libANGLE/renderer/vulkan/ContextVk.h" 16 17 namespace rx 18 { 19 ShaderVk(const gl::ShaderState & state)20ShaderVk::ShaderVk(const gl::ShaderState &state) : ShaderImpl(state) {} 21 ~ShaderVk()22ShaderVk::~ShaderVk() {} 23 compile(const gl::Context * context,gl::ShCompilerInstance * compilerInstance,ShCompileOptions * options)24std::shared_ptr<WaitableCompileEvent> ShaderVk::compile(const gl::Context *context, 25 gl::ShCompilerInstance *compilerInstance, 26 ShCompileOptions *options) 27 { 28 ContextVk *contextVk = vk::GetImpl(context); 29 30 if (context->isWebGL()) 31 { 32 // Only WebGL requires initialization of local variables, others don't. 33 // Extra initialization in spirv shader may affect performance. 34 options->initializeUninitializedLocals = true; 35 36 // WebGL shaders may contain OOB array accesses which in turn cause undefined behavior, 37 // which may result in security issues. See https://crbug.com/1189110. 38 options->clampIndirectArrayBounds = true; 39 40 if (mState.getShaderType() != gl::ShaderType::Compute) 41 { 42 options->initOutputVariables = true; 43 } 44 } 45 46 if (contextVk->getFeatures().retainSPIRVDebugInfo.enabled) 47 { 48 options->outputDebugInfo = true; 49 } 50 51 // robustBufferAccess on Vulkan doesn't support bound check on shader local variables 52 // but the GL_EXT_robustness does support. 53 // Enable the flag clampIndirectArrayBounds to ensure out of bounds local variable writes in 54 // shaders are protected when the context has GL_EXT_robustness enabled 55 if (contextVk->getShareGroup()->hasAnyContextWithRobustness()) 56 { 57 options->clampIndirectArrayBounds = true; 58 } 59 60 if (contextVk->getFeatures().clampPointSize.enabled) 61 { 62 options->clampPointSize = true; 63 } 64 65 if (contextVk->getFeatures().emulateAdvancedBlendEquations.enabled) 66 { 67 options->addAdvancedBlendEquationsEmulation = true; 68 } 69 70 if (contextVk->emulateSeamfulCubeMapSampling()) 71 { 72 options->emulateSeamfulCubeMapSampling = true; 73 } 74 75 if (!contextVk->getFeatures().enablePrecisionQualifiers.enabled) 76 { 77 options->ignorePrecisionQualifiers = true; 78 } 79 80 if (contextVk->getFeatures().forceFragmentShaderPrecisionHighpToMediump.enabled) 81 { 82 options->forceShaderPrecisionHighpToMediump = true; 83 } 84 85 // Let compiler use specialized constant for pre-rotation. 86 if (!contextVk->getFeatures().preferDriverUniformOverSpecConst.enabled) 87 { 88 options->useSpecializationConstant = true; 89 } 90 91 if (contextVk->getFeatures().clampFragDepth.enabled) 92 { 93 options->clampFragDepth = true; 94 } 95 96 if (!contextVk->getFeatures().supportsDepthClipControl.enabled) 97 { 98 options->addVulkanDepthCorrection = true; 99 } 100 101 if (contextVk->getFeatures().supportsTransformFeedbackExtension.enabled) 102 { 103 options->addVulkanXfbExtensionSupportCode = true; 104 } 105 else if (mState.getShaderType() == gl::ShaderType::Vertex && 106 contextVk->getFeatures().emulateTransformFeedback.enabled) 107 { 108 options->addVulkanXfbEmulationSupportCode = true; 109 } 110 111 if (contextVk->getFeatures().roundOutputAfterDithering.enabled) 112 { 113 options->roundOutputAfterDithering = true; 114 } 115 116 if (contextVk->getFeatures().appendAliasedMemoryDecorations.enabled) 117 { 118 options->aliasedUnlessRestrict = true; 119 } 120 121 if (contextVk->getFeatures().explicitlyCastMediumpFloatTo16Bit.enabled) 122 { 123 options->castMediumpFloatTo16Bit = true; 124 } 125 126 if (contextVk->getExtensions().shaderPixelLocalStorageANGLE) 127 { 128 options->pls = contextVk->getNativePixelLocalStorageOptions(); 129 } 130 131 return compileImpl(context, compilerInstance, mState.getSource(), options); 132 } 133 getDebugInfo() const134std::string ShaderVk::getDebugInfo() const 135 { 136 return mState.getCompiledBinary().empty() ? "" : "<binary blob>"; 137 } 138 139 } // namespace rx 140