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