• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)20 ShaderVk::ShaderVk(const gl::ShaderState &state) : ShaderImpl(state) {}
21 
~ShaderVk()22 ShaderVk::~ShaderVk() {}
23 
compile(const gl::Context * context,gl::ShCompilerInstance * compilerInstance,ShCompileOptions options)24 std::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() const117 std::string ShaderVk::getDebugInfo() const
118 {
119     return mState.getCompiledBinary().empty() ? "" : "<binary blob>";
120 }
121 
122 }  // namespace rx
123