зеркало из https://github.com/AvaloniaUI/angle.git
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 <syoussefi@chromium.org> Reviewed-by: Tim Van Patten <timvp@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Родитель
91295e1aab
Коммит
5dfad811ce
|
@ -206,6 +206,45 @@ std::string TOutputGLSLBase::getCommonLayoutQualifiers(TIntermTyped *variable)
|
|||
return out.str();
|
||||
}
|
||||
|
||||
// Outputs what comes after in/out/uniform/buffer storage qualifier.
|
||||
std::string TOutputGLSLBase::getMemoryQualifiers(const TType &type)
|
||||
{
|
||||
std::ostringstream out;
|
||||
|
||||
const TMemoryQualifier &memoryQualifier = type.getMemoryQualifier();
|
||||
if (memoryQualifier.readonly)
|
||||
{
|
||||
ASSERT(IsImage(type.getBasicType()));
|
||||
out << "readonly ";
|
||||
}
|
||||
|
||||
if (memoryQualifier.writeonly)
|
||||
{
|
||||
ASSERT(IsImage(type.getBasicType()));
|
||||
out << "writeonly ";
|
||||
}
|
||||
|
||||
if (memoryQualifier.coherent)
|
||||
{
|
||||
ASSERT(IsImage(type.getBasicType()));
|
||||
out << "coherent ";
|
||||
}
|
||||
|
||||
if (memoryQualifier.restrictQualifier)
|
||||
{
|
||||
ASSERT(IsImage(type.getBasicType()));
|
||||
out << "restrict ";
|
||||
}
|
||||
|
||||
if (memoryQualifier.volatileQualifier)
|
||||
{
|
||||
ASSERT(IsImage(type.getBasicType()));
|
||||
out << "volatile ";
|
||||
}
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void TOutputGLSLBase::writeLayoutQualifier(TIntermTyped *variable)
|
||||
{
|
||||
const TType &type = variable->getType();
|
||||
|
@ -261,6 +300,8 @@ void TOutputGLSLBase::writeQualifier(TQualifier qualifier, const TType &type, co
|
|||
{
|
||||
objSink() << result << " ";
|
||||
}
|
||||
|
||||
objSink() << getMemoryQualifiers(type);
|
||||
}
|
||||
|
||||
const char *TOutputGLSLBase::mapQualifierToString(TQualifier qualifier)
|
||||
|
@ -312,37 +353,6 @@ void TOutputGLSLBase::writeVariableType(const TType &type, const TSymbol *symbol
|
|||
writeQualifier(qualifier, type, symbol);
|
||||
}
|
||||
|
||||
const TMemoryQualifier &memoryQualifier = type.getMemoryQualifier();
|
||||
if (memoryQualifier.readonly)
|
||||
{
|
||||
ASSERT(IsImage(type.getBasicType()));
|
||||
out << "readonly ";
|
||||
}
|
||||
|
||||
if (memoryQualifier.writeonly)
|
||||
{
|
||||
ASSERT(IsImage(type.getBasicType()));
|
||||
out << "writeonly ";
|
||||
}
|
||||
|
||||
if (memoryQualifier.coherent)
|
||||
{
|
||||
ASSERT(IsImage(type.getBasicType()));
|
||||
out << "coherent ";
|
||||
}
|
||||
|
||||
if (memoryQualifier.restrictQualifier)
|
||||
{
|
||||
ASSERT(IsImage(type.getBasicType()));
|
||||
out << "restrict ";
|
||||
}
|
||||
|
||||
if (memoryQualifier.volatileQualifier)
|
||||
{
|
||||
ASSERT(IsImage(type.getBasicType()));
|
||||
out << "volatile ";
|
||||
}
|
||||
|
||||
// Declare the struct if we have not done so already.
|
||||
if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct()))
|
||||
{
|
||||
|
|
|
@ -41,6 +41,7 @@ class TOutputGLSLBase : public TIntermTraverser
|
|||
void writeFloat(TInfoSinkBase &out, float f);
|
||||
void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr);
|
||||
std::string getCommonLayoutQualifiers(TIntermTyped *variable);
|
||||
std::string getMemoryQualifiers(const TType &type);
|
||||
virtual void writeLayoutQualifier(TIntermTyped *variable);
|
||||
void writeInvariantQualifier(const TType &type);
|
||||
virtual void writeVariableType(const TType &type, const TSymbol *symbol);
|
||||
|
|
|
@ -133,8 +133,8 @@ void TOutputVulkanGLSL::writeQualifier(TQualifier qualifier,
|
|||
const TType &type,
|
||||
const TSymbol *symbol)
|
||||
{
|
||||
if (qualifier != EvqUniform && qualifier != EvqAttribute && qualifier != EvqVertexIn &&
|
||||
!sh::IsVarying(qualifier))
|
||||
if (qualifier != EvqUniform && qualifier != EvqBuffer && qualifier != EvqAttribute &&
|
||||
qualifier != EvqVertexIn && !sh::IsVarying(qualifier))
|
||||
{
|
||||
TOutputGLSLBase::writeQualifier(qualifier, type, symbol);
|
||||
return;
|
||||
|
@ -155,7 +155,7 @@ void TOutputVulkanGLSL::writeQualifier(TQualifier qualifier,
|
|||
}
|
||||
|
||||
TInfoSinkBase &out = objSink();
|
||||
out << "@@ QUALIFIER-" << name.data() << " @@ ";
|
||||
out << "@@ QUALIFIER-" << name.data() << "(" << getMemoryQualifiers(type) << ") @@ ";
|
||||
}
|
||||
|
||||
void TOutputVulkanGLSL::writeVariableType(const TType &type, const TSymbol *symbol)
|
||||
|
|
|
@ -40,8 +40,8 @@ constexpr char kLayoutMarkerBegin[] = "@@ LAYOUT-";
|
|||
constexpr char kXfbDeclMarkerBegin[] = "@@ XFB-DECL";
|
||||
constexpr char kXfbOutMarkerBegin[] = "@@ XFB-OUT";
|
||||
constexpr char kMarkerEnd[] = " @@";
|
||||
constexpr char kLayoutParamsBegin = '(';
|
||||
constexpr char kLayoutParamsEnd = ')';
|
||||
constexpr char kParamsBegin = '(';
|
||||
constexpr char kParamsEnd = ')';
|
||||
constexpr char kUniformQualifier[] = "uniform";
|
||||
constexpr char kVersionDefine[] = "#version 450 core\n";
|
||||
constexpr char kLineRasterDefine[] = R"(#version 450 core
|
||||
|
@ -101,13 +101,18 @@ class IntermediateShaderSource final : angle::NonCopyable
|
|||
//
|
||||
// layout(specifier, extra, args)
|
||||
//
|
||||
// or if specifier is empty,
|
||||
// or if |specifier| is empty:
|
||||
//
|
||||
// layout(extra, args)
|
||||
//
|
||||
void insertLayoutSpecifier(const std::string &name, const std::string &specifier);
|
||||
|
||||
// Find @@ QUALIFIER-name @@ and replace it with |specifier|.
|
||||
// Find @@ QUALIFIER-name(other qualifiers) @@ and replace it with:
|
||||
//
|
||||
// specifier other qualifiers
|
||||
//
|
||||
// or if |specifier| is empty, with nothing.
|
||||
//
|
||||
void insertQualifierSpecifier(const std::string &name, const std::string &specifier);
|
||||
|
||||
// Replace @@ XFB-DECL @@ with |decl|.
|
||||
|
@ -116,7 +121,7 @@ class IntermediateShaderSource final : angle::NonCopyable
|
|||
// Replace @@ XFB-OUT @@ with |output| code block.
|
||||
void insertTransformFeedbackOutput(const std::string &&output);
|
||||
|
||||
// Remove @@ LAYOUT-name(*) @@ and @@ QUALIFIER-name @@ altogether, optionally replacing them
|
||||
// Remove @@ LAYOUT-name(*) @@ and @@ QUALIFIER-name(*) @@ altogether, optionally replacing them
|
||||
// with something to make sure the shader still compiles.
|
||||
void eraseLayoutAndQualifierSpecifiers(const std::string &name, const std::string &replacement);
|
||||
|
||||
|
@ -128,7 +133,7 @@ class IntermediateShaderSource final : angle::NonCopyable
|
|||
{
|
||||
// A piece of shader source code.
|
||||
Text,
|
||||
// Block corresponding to @@ QUALIFIER-abc @@
|
||||
// Block corresponding to @@ QUALIFIER-abc(other qualifiers) @@
|
||||
Qualifier,
|
||||
// Block corresponding to @@ LAYOUT-abc(extra, args) @@
|
||||
Layout,
|
||||
|
@ -144,13 +149,13 @@ class IntermediateShaderSource final : angle::NonCopyable
|
|||
// |text| contains some shader code if Text, or the id of macro ("abc" in examples above)
|
||||
// being replaced if Qualifier or Layout.
|
||||
std::string text;
|
||||
// If Layout, this contains extra parameters passed in parentheses, if any.
|
||||
// If Qualifier or Layout, this contains extra parameters passed in parentheses, if any.
|
||||
std::string args;
|
||||
};
|
||||
|
||||
void addTextBlock(std::string &&text);
|
||||
void addLayoutBlock(std::string &&name, std::string &&args);
|
||||
void addQualifierBlock(std::string &&name);
|
||||
void addQualifierBlock(std::string &&name, std::string &&args);
|
||||
void addTransformFeedbackDeclarationBlock();
|
||||
void addTransformFeedbackOutputBlock();
|
||||
|
||||
|
@ -175,10 +180,10 @@ void IntermediateShaderSource::addLayoutBlock(std::string &&name, std::string &&
|
|||
mTokens.emplace_back(std::move(token));
|
||||
}
|
||||
|
||||
void IntermediateShaderSource::addQualifierBlock(std::string &&name)
|
||||
void IntermediateShaderSource::addQualifierBlock(std::string &&name, std::string &&args)
|
||||
{
|
||||
ASSERT(!name.empty());
|
||||
Token token = {TokenType::Qualifier, std::move(name), ""};
|
||||
Token token = {TokenType::Qualifier, std::move(name), std::move(args)};
|
||||
mTokens.emplace_back(std::move(token));
|
||||
}
|
||||
|
||||
|
@ -194,6 +199,21 @@ void IntermediateShaderSource::addTransformFeedbackOutputBlock()
|
|||
mTokens.emplace_back(std::move(token));
|
||||
}
|
||||
|
||||
size_t ExtractNameAndArgs(const std::string &source,
|
||||
size_t cur,
|
||||
std::string *nameOut,
|
||||
std::string *argsOut)
|
||||
{
|
||||
*nameOut = angle::GetPrefix(source, cur, kParamsBegin);
|
||||
|
||||
// There should always be an extra args list (even if empty, for simplicity).
|
||||
size_t readCount = nameOut->length() + 1;
|
||||
*argsOut = angle::GetPrefix(source, cur + readCount, kParamsEnd);
|
||||
readCount += argsOut->length() + 1;
|
||||
|
||||
return readCount;
|
||||
}
|
||||
|
||||
IntermediateShaderSource::IntermediateShaderSource(const std::string &source)
|
||||
{
|
||||
size_t cur = 0;
|
||||
|
@ -216,21 +236,18 @@ IntermediateShaderSource::IntermediateShaderSource(const std::string &source)
|
|||
{
|
||||
cur += ConstStrLen(kQualifierMarkerBegin);
|
||||
|
||||
// Get the id of the macro and add a qualifier block.
|
||||
std::string name = angle::GetPrefix(source, cur, kMarkerEnd);
|
||||
cur += name.length();
|
||||
addQualifierBlock(std::move(name));
|
||||
// Get the id and arguments of the macro and add a qualifier block.
|
||||
std::string name, args;
|
||||
cur += ExtractNameAndArgs(source, cur, &name, &args);
|
||||
addQualifierBlock(std::move(name), std::move(args));
|
||||
}
|
||||
else if (source.compare(cur, ConstStrLen(kLayoutMarkerBegin), kLayoutMarkerBegin) == 0)
|
||||
{
|
||||
cur += ConstStrLen(kLayoutMarkerBegin);
|
||||
|
||||
// Get the id and arguments of the macro and add a layout block.
|
||||
// There should always be an extra args list (even if empty, for simplicity).
|
||||
std::string name = angle::GetPrefix(source, cur, kLayoutParamsBegin);
|
||||
cur += name.length() + 1;
|
||||
std::string args = angle::GetPrefix(source, cur, kLayoutParamsEnd);
|
||||
cur += args.length() + 1;
|
||||
std::string name, args;
|
||||
cur += ExtractNameAndArgs(source, cur, &name, &args);
|
||||
addLayoutBlock(std::move(name), std::move(args));
|
||||
}
|
||||
else if (source.compare(cur, ConstStrLen(kXfbDeclMarkerBegin), kXfbDeclMarkerBegin) == 0)
|
||||
|
@ -283,6 +300,10 @@ void IntermediateShaderSource::insertQualifierSpecifier(const std::string &name,
|
|||
{
|
||||
block.type = TokenType::Text;
|
||||
block.text = specifier;
|
||||
if (!specifier.empty() && !block.args.empty())
|
||||
{
|
||||
block.text += " " + block.args;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче