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