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/renderer/vulkan/ContextVk.h" 15 #include "platform/FeaturesVk.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 ShCompileOptions compileOptions = 0; 29 30 ContextVk *contextVk = vk::GetImpl(context); 31 32 bool isWebGL = context->getExtensions().webglCompatibility; 33 34 if (isWebGL) 35 { 36 // Only webgl requires initialization of local variables, others don't. 37 // Extra initialization in spirv shader may affect performance. 38 compileOptions |= SH_INITIALIZE_UNINITIALIZED_LOCALS; 39 40 // WebGL shaders may contain OOB array accesses which in turn cause undefined behavior, 41 // which may result in security issues. See https://crbug.com/1189110. 42 compileOptions |= SH_CLAMP_INDIRECT_ARRAY_BOUNDS; 43 44 if (mState.getShaderType() != gl::ShaderType::Compute) 45 { 46 compileOptions |= SH_INIT_OUTPUT_VARIABLES; 47 } 48 } 49 50 if (contextVk->getFeatures().clampPointSize.enabled) 51 { 52 compileOptions |= SH_CLAMP_POINT_SIZE; 53 } 54 55 if (contextVk->getFeatures().basicGLLineRasterization.enabled) 56 { 57 compileOptions |= SH_ADD_BRESENHAM_LINE_RASTER_EMULATION; 58 } 59 60 if (contextVk->emulateSeamfulCubeMapSampling()) 61 { 62 compileOptions |= SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING; 63 } 64 65 if (!contextVk->getFeatures().enablePrecisionQualifiers.enabled) 66 { 67 compileOptions |= SH_IGNORE_PRECISION_QUALIFIERS; 68 } 69 70 if (contextVk->getFeatures().forceFragmentShaderPrecisionHighpToMediump.enabled) 71 { 72 compileOptions |= SH_FORCE_SHADER_PRECISION_HIGHP_TO_MEDIUMP; 73 } 74 75 // Let compiler detect and emit early fragment test execution mode. We will remove it if 76 // context state does not allow it 77 compileOptions |= SH_EARLY_FRAGMENT_TESTS_OPTIMIZATION; 78 79 // Let compiler use specialized constant for pre-rotation. 80 if (!contextVk->getFeatures().forceDriverUniformOverSpecConst.enabled) 81 { 82 compileOptions |= SH_USE_SPECIALIZATION_CONSTANT; 83 } 84 85 if (contextVk->getFeatures().enablePreRotateSurfaces.enabled || 86 contextVk->getFeatures().emulatedPrerotation90.enabled || 87 contextVk->getFeatures().emulatedPrerotation180.enabled || 88 contextVk->getFeatures().emulatedPrerotation270.enabled) 89 { 90 // Let compiler insert pre-rotation code. 91 compileOptions |= SH_ADD_PRE_ROTATION; 92 } 93 94 if (contextVk->getFeatures().supportsTransformFeedbackExtension.enabled) 95 { 96 compileOptions |= SH_ADD_VULKAN_XFB_EXTENSION_SUPPORT_CODE; 97 } 98 else if (mState.getShaderType() == gl::ShaderType::Vertex && 99 contextVk->getFeatures().emulateTransformFeedback.enabled) 100 { 101 compileOptions |= SH_ADD_VULKAN_XFB_EMULATION_SUPPORT_CODE; 102 } 103 104 if (contextVk->getFeatures().directSPIRVGeneration.enabled) 105 { 106 compileOptions |= SH_GENERATE_SPIRV_DIRECTLY; 107 108 if (contextVk->getFeatures().directSPIRVGenerationWorkarounds.enabled) 109 { 110 compileOptions |= SH_GENERATE_SPIRV_WORKAROUNDS; 111 } 112 } 113 114 return compileImpl(context, compilerInstance, mState.getSource(), compileOptions | options); 115 } 116 getDebugInfo() const117std::string ShaderVk::getDebugInfo() const 118 { 119 return mState.getCompiledBinary().empty() ? "" : "<binary blob>"; 120 } 121 122 } // namespace rx 123