Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 5dfad81

Browse files
ShabbyXCommit Bot
authored andcommitted
Vulkan: GLSL output support for SSBO memory qualifiers
Makes the QUALIFIER macro take arguments similar to LAYOUT, to allow passing in tokens to be conditionally output after the storage qualifier. Bug: angleproject:3561 Change-Id: I4368eba2c34c1398f81d33cd23c9e56557fd4ed8 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1685876 Commit-Queue: Shahbaz Youssefi <[email protected]> Reviewed-by: Tim Van Patten <[email protected]> Reviewed-by: Jamie Madill <[email protected]>
1 parent 91295e1 commit 5dfad81

File tree

4 files changed

+85
-53
lines changed

4 files changed

+85
-53
lines changed

src/compiler/translator/OutputGLSLBase.cpp

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,45 @@ std::string TOutputGLSLBase::getCommonLayoutQualifiers(TIntermTyped *variable)
206206
return out.str();
207207
}
208208

209+
// Outputs what comes after in/out/uniform/buffer storage qualifier.
210+
std::string TOutputGLSLBase::getMemoryQualifiers(const TType &type)
211+
{
212+
std::ostringstream out;
213+
214+
const TMemoryQualifier &memoryQualifier = type.getMemoryQualifier();
215+
if (memoryQualifier.readonly)
216+
{
217+
ASSERT(IsImage(type.getBasicType()));
218+
out << "readonly ";
219+
}
220+
221+
if (memoryQualifier.writeonly)
222+
{
223+
ASSERT(IsImage(type.getBasicType()));
224+
out << "writeonly ";
225+
}
226+
227+
if (memoryQualifier.coherent)
228+
{
229+
ASSERT(IsImage(type.getBasicType()));
230+
out << "coherent ";
231+
}
232+
233+
if (memoryQualifier.restrictQualifier)
234+
{
235+
ASSERT(IsImage(type.getBasicType()));
236+
out << "restrict ";
237+
}
238+
239+
if (memoryQualifier.volatileQualifier)
240+
{
241+
ASSERT(IsImage(type.getBasicType()));
242+
out << "volatile ";
243+
}
244+
245+
return out.str();
246+
}
247+
209248
void TOutputGLSLBase::writeLayoutQualifier(TIntermTyped *variable)
210249
{
211250
const TType &type = variable->getType();
@@ -261,6 +300,8 @@ void TOutputGLSLBase::writeQualifier(TQualifier qualifier, const TType &type, co
261300
{
262301
objSink() << result << " ";
263302
}
303+
304+
objSink() << getMemoryQualifiers(type);
264305
}
265306

266307
const char *TOutputGLSLBase::mapQualifierToString(TQualifier qualifier)
@@ -312,37 +353,6 @@ void TOutputGLSLBase::writeVariableType(const TType &type, const TSymbol *symbol
312353
writeQualifier(qualifier, type, symbol);
313354
}
314355

315-
const TMemoryQualifier &memoryQualifier = type.getMemoryQualifier();
316-
if (memoryQualifier.readonly)
317-
{
318-
ASSERT(IsImage(type.getBasicType()));
319-
out << "readonly ";
320-
}
321-
322-
if (memoryQualifier.writeonly)
323-
{
324-
ASSERT(IsImage(type.getBasicType()));
325-
out << "writeonly ";
326-
}
327-
328-
if (memoryQualifier.coherent)
329-
{
330-
ASSERT(IsImage(type.getBasicType()));
331-
out << "coherent ";
332-
}
333-
334-
if (memoryQualifier.restrictQualifier)
335-
{
336-
ASSERT(IsImage(type.getBasicType()));
337-
out << "restrict ";
338-
}
339-
340-
if (memoryQualifier.volatileQualifier)
341-
{
342-
ASSERT(IsImage(type.getBasicType()));
343-
out << "volatile ";
344-
}
345-
346356
// Declare the struct if we have not done so already.
347357
if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct()))
348358
{

src/compiler/translator/OutputGLSLBase.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class TOutputGLSLBase : public TIntermTraverser
4141
void writeFloat(TInfoSinkBase &out, float f);
4242
void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr);
4343
std::string getCommonLayoutQualifiers(TIntermTyped *variable);
44+
std::string getMemoryQualifiers(const TType &type);
4445
virtual void writeLayoutQualifier(TIntermTyped *variable);
4546
void writeInvariantQualifier(const TType &type);
4647
virtual void writeVariableType(const TType &type, const TSymbol *symbol);

src/compiler/translator/OutputVulkanGLSL.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ void TOutputVulkanGLSL::writeQualifier(TQualifier qualifier,
133133
const TType &type,
134134
const TSymbol *symbol)
135135
{
136-
if (qualifier != EvqUniform && qualifier != EvqAttribute && qualifier != EvqVertexIn &&
137-
!sh::IsVarying(qualifier))
136+
if (qualifier != EvqUniform && qualifier != EvqBuffer && qualifier != EvqAttribute &&
137+
qualifier != EvqVertexIn && !sh::IsVarying(qualifier))
138138
{
139139
TOutputGLSLBase::writeQualifier(qualifier, type, symbol);
140140
return;
@@ -155,7 +155,7 @@ void TOutputVulkanGLSL::writeQualifier(TQualifier qualifier,
155155
}
156156

157157
TInfoSinkBase &out = objSink();
158-
out << "@@ QUALIFIER-" << name.data() << " @@ ";
158+
out << "@@ QUALIFIER-" << name.data() << "(" << getMemoryQualifiers(type) << ") @@ ";
159159
}
160160

161161
void TOutputVulkanGLSL::writeVariableType(const TType &type, const TSymbol *symbol)

src/libANGLE/renderer/vulkan/GlslangWrapper.cpp

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ constexpr char kLayoutMarkerBegin[] = "@@ LAYOUT-";
4040
constexpr char kXfbDeclMarkerBegin[] = "@@ XFB-DECL";
4141
constexpr char kXfbOutMarkerBegin[] = "@@ XFB-OUT";
4242
constexpr char kMarkerEnd[] = " @@";
43-
constexpr char kLayoutParamsBegin = '(';
44-
constexpr char kLayoutParamsEnd = ')';
43+
constexpr char kParamsBegin = '(';
44+
constexpr char kParamsEnd = ')';
4545
constexpr char kUniformQualifier[] = "uniform";
4646
constexpr char kVersionDefine[] = "#version 450 core\n";
4747
constexpr char kLineRasterDefine[] = R"(#version 450 core
@@ -101,13 +101,18 @@ class IntermediateShaderSource final : angle::NonCopyable
101101
//
102102
// layout(specifier, extra, args)
103103
//
104-
// or if specifier is empty,
104+
// or if |specifier| is empty:
105105
//
106106
// layout(extra, args)
107107
//
108108
void insertLayoutSpecifier(const std::string &name, const std::string &specifier);
109109

110-
// Find @@ QUALIFIER-name @@ and replace it with |specifier|.
110+
// Find @@ QUALIFIER-name(other qualifiers) @@ and replace it with:
111+
//
112+
// specifier other qualifiers
113+
//
114+
// or if |specifier| is empty, with nothing.
115+
//
111116
void insertQualifierSpecifier(const std::string &name, const std::string &specifier);
112117

113118
// Replace @@ XFB-DECL @@ with |decl|.
@@ -116,7 +121,7 @@ class IntermediateShaderSource final : angle::NonCopyable
116121
// Replace @@ XFB-OUT @@ with |output| code block.
117122
void insertTransformFeedbackOutput(const std::string &&output);
118123

119-
// Remove @@ LAYOUT-name(*) @@ and @@ QUALIFIER-name @@ altogether, optionally replacing them
124+
// Remove @@ LAYOUT-name(*) @@ and @@ QUALIFIER-name(*) @@ altogether, optionally replacing them
120125
// with something to make sure the shader still compiles.
121126
void eraseLayoutAndQualifierSpecifiers(const std::string &name, const std::string &replacement);
122127

@@ -128,7 +133,7 @@ class IntermediateShaderSource final : angle::NonCopyable
128133
{
129134
// A piece of shader source code.
130135
Text,
131-
// Block corresponding to @@ QUALIFIER-abc @@
136+
// Block corresponding to @@ QUALIFIER-abc(other qualifiers) @@
132137
Qualifier,
133138
// Block corresponding to @@ LAYOUT-abc(extra, args) @@
134139
Layout,
@@ -144,13 +149,13 @@ class IntermediateShaderSource final : angle::NonCopyable
144149
// |text| contains some shader code if Text, or the id of macro ("abc" in examples above)
145150
// being replaced if Qualifier or Layout.
146151
std::string text;
147-
// If Layout, this contains extra parameters passed in parentheses, if any.
152+
// If Qualifier or Layout, this contains extra parameters passed in parentheses, if any.
148153
std::string args;
149154
};
150155

151156
void addTextBlock(std::string &&text);
152157
void addLayoutBlock(std::string &&name, std::string &&args);
153-
void addQualifierBlock(std::string &&name);
158+
void addQualifierBlock(std::string &&name, std::string &&args);
154159
void addTransformFeedbackDeclarationBlock();
155160
void addTransformFeedbackOutputBlock();
156161

@@ -175,10 +180,10 @@ void IntermediateShaderSource::addLayoutBlock(std::string &&name, std::string &&
175180
mTokens.emplace_back(std::move(token));
176181
}
177182

178-
void IntermediateShaderSource::addQualifierBlock(std::string &&name)
183+
void IntermediateShaderSource::addQualifierBlock(std::string &&name, std::string &&args)
179184
{
180185
ASSERT(!name.empty());
181-
Token token = {TokenType::Qualifier, std::move(name), ""};
186+
Token token = {TokenType::Qualifier, std::move(name), std::move(args)};
182187
mTokens.emplace_back(std::move(token));
183188
}
184189

@@ -194,6 +199,21 @@ void IntermediateShaderSource::addTransformFeedbackOutputBlock()
194199
mTokens.emplace_back(std::move(token));
195200
}
196201

202+
size_t ExtractNameAndArgs(const std::string &source,
203+
size_t cur,
204+
std::string *nameOut,
205+
std::string *argsOut)
206+
{
207+
*nameOut = angle::GetPrefix(source, cur, kParamsBegin);
208+
209+
// There should always be an extra args list (even if empty, for simplicity).
210+
size_t readCount = nameOut->length() + 1;
211+
*argsOut = angle::GetPrefix(source, cur + readCount, kParamsEnd);
212+
readCount += argsOut->length() + 1;
213+
214+
return readCount;
215+
}
216+
197217
IntermediateShaderSource::IntermediateShaderSource(const std::string &source)
198218
{
199219
size_t cur = 0;
@@ -216,21 +236,18 @@ IntermediateShaderSource::IntermediateShaderSource(const std::string &source)
216236
{
217237
cur += ConstStrLen(kQualifierMarkerBegin);
218238

219-
// Get the id of the macro and add a qualifier block.
220-
std::string name = angle::GetPrefix(source, cur, kMarkerEnd);
221-
cur += name.length();
222-
addQualifierBlock(std::move(name));
239+
// Get the id and arguments of the macro and add a qualifier block.
240+
std::string name, args;
241+
cur += ExtractNameAndArgs(source, cur, &name, &args);
242+
addQualifierBlock(std::move(name), std::move(args));
223243
}
224244
else if (source.compare(cur, ConstStrLen(kLayoutMarkerBegin), kLayoutMarkerBegin) == 0)
225245
{
226246
cur += ConstStrLen(kLayoutMarkerBegin);
227247

228248
// Get the id and arguments of the macro and add a layout block.
229-
// There should always be an extra args list (even if empty, for simplicity).
230-
std::string name = angle::GetPrefix(source, cur, kLayoutParamsBegin);
231-
cur += name.length() + 1;
232-
std::string args = angle::GetPrefix(source, cur, kLayoutParamsEnd);
233-
cur += args.length() + 1;
249+
std::string name, args;
250+
cur += ExtractNameAndArgs(source, cur, &name, &args);
234251
addLayoutBlock(std::move(name), std::move(args));
235252
}
236253
else if (source.compare(cur, ConstStrLen(kXfbDeclMarkerBegin), kXfbDeclMarkerBegin) == 0)
@@ -283,6 +300,10 @@ void IntermediateShaderSource::insertQualifierSpecifier(const std::string &name,
283300
{
284301
block.type = TokenType::Text;
285302
block.text = specifier;
303+
if (!specifier.empty() && !block.args.empty())
304+
{
305+
block.text += " " + block.args;
306+
}
286307
break;
287308
}
288309
}

0 commit comments

Comments
 (0)