• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2017 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 // ProgramPipelineVk.cpp:
7 //    Implements the class methods for ProgramPipelineVk.
8 //
9 
10 #include "libANGLE/renderer/vulkan/ProgramPipelineVk.h"
11 
12 #include "libANGLE/renderer/glslang_wrapper_utils.h"
13 #include "libANGLE/renderer/vulkan/GlslangWrapperVk.h"
14 
15 namespace rx
16 {
17 
ProgramPipelineVk(const gl::ProgramPipelineState & state)18 ProgramPipelineVk::ProgramPipelineVk(const gl::ProgramPipelineState &state)
19     : ProgramPipelineImpl(state)
20 {}
21 
~ProgramPipelineVk()22 ProgramPipelineVk::~ProgramPipelineVk() {}
23 
destroy(const gl::Context * context)24 void ProgramPipelineVk::destroy(const gl::Context *context)
25 {
26     ContextVk *contextVk = vk::GetImpl(context);
27     reset(contextVk);
28 }
29 
reset(ContextVk * contextVk)30 void ProgramPipelineVk::reset(ContextVk *contextVk)
31 {
32     mExecutable.reset(contextVk);
33 }
34 
link(const gl::Context * glContext,const gl::ProgramMergedVaryings & mergedVaryings,const gl::ProgramVaryingPacking & varyingPacking)35 angle::Result ProgramPipelineVk::link(const gl::Context *glContext,
36                                       const gl::ProgramMergedVaryings &mergedVaryings,
37                                       const gl::ProgramVaryingPacking &varyingPacking)
38 {
39     ContextVk *contextVk                      = vk::GetImpl(glContext);
40     const gl::ProgramExecutable &glExecutable = mState.getExecutable();
41     GlslangSourceOptions options =
42         GlslangWrapperVk::CreateSourceOptions(contextVk->getRenderer()->getFeatures());
43     GlslangProgramInterfaceInfo glslangProgramInterfaceInfo;
44     GlslangWrapperVk::ResetGlslangProgramInterfaceInfo(&glslangProgramInterfaceInfo);
45 
46     mExecutable.clearVariableInfoMap();
47 
48     // Now that the program pipeline has all of the programs attached, the various descriptor
49     // set/binding locations need to be re-assigned to their correct values.
50     const gl::ShaderType linkedTransformFeedbackStage =
51         glExecutable.getLinkedTransformFeedbackStage();
52 
53     // This should be done before assigning varying locations. Otherwise, we can encounter shader
54     // interface mismatching problems when the transform feedback stage is not the vertex stage.
55     if (options.supportsTransformFeedbackExtension)
56     {
57         for (const gl::ShaderType shaderType : glExecutable.getLinkedShaderStages())
58         {
59             const gl::Program *glProgram = mState.getShaderProgram(shaderType);
60             if (glProgram && gl::ShaderTypeSupportsTransformFeedback(shaderType))
61             {
62                 const bool isTransformFeedbackStage =
63                     shaderType == linkedTransformFeedbackStage &&
64                     !glProgram->getState().getLinkedTransformFeedbackVaryings().empty();
65 
66                 GlslangAssignTransformFeedbackLocations(
67                     shaderType, glProgram->getExecutable(), isTransformFeedbackStage,
68                     &glslangProgramInterfaceInfo, &mExecutable.mVariableInfoMap);
69             }
70         }
71     }
72 
73     mExecutable.mOriginalShaderInfo.clear();
74 
75     gl::ShaderType frontShaderType = gl::ShaderType::InvalidEnum;
76     UniformBindingIndexMap uniformBindingIndexMap;
77     for (const gl::ShaderType shaderType : glExecutable.getLinkedShaderStages())
78     {
79         const bool isTransformFeedbackStage =
80             shaderType == linkedTransformFeedbackStage &&
81             !glExecutable.getLinkedTransformFeedbackVaryings().empty();
82 
83         GlslangAssignLocations(options, glExecutable, varyingPacking, shaderType, frontShaderType,
84                                isTransformFeedbackStage, &glslangProgramInterfaceInfo,
85                                &uniformBindingIndexMap, &mExecutable.mVariableInfoMap);
86         frontShaderType = shaderType;
87 
88         const gl::Program *program               = mState.getShaderProgram(shaderType);
89         ProgramVk *programVk                     = vk::GetImpl(program);
90         ProgramExecutableVk &programExecutableVk = programVk->getExecutable();
91         mExecutable.mDefaultUniformBlocks[shaderType] =
92             programExecutableVk.getSharedDefaultUniformBlock(shaderType);
93 
94         mExecutable.mOriginalShaderInfo.initShaderFromProgram(
95             shaderType, programExecutableVk.mOriginalShaderInfo);
96     }
97 
98     mExecutable.setAllDefaultUniformsDirty(glExecutable);
99 
100     if (contextVk->getFeatures().enablePrecisionQualifiers.enabled)
101     {
102         mExecutable.resolvePrecisionMismatch(mergedVaryings);
103     }
104 
105     return mExecutable.createPipelineLayout(contextVk, mState.getExecutable(), nullptr);
106 }  // namespace rx
107 
onProgramUniformUpdate(gl::ShaderType shaderType)108 void ProgramPipelineVk::onProgramUniformUpdate(gl::ShaderType shaderType)
109 {
110     mExecutable.mDefaultUniformBlocksDirty.set(shaderType);
111 }
112 }  // namespace rx
113