Commit c0bb36cb by Jamie Madill Committed by Commit Bot

Vulkan: Add driver uniforms to shader.

Bug: angleproject:2717 Change-Id: I542f3b0f2de21857d7fea0267f07d2d0eec78a8c Reviewed-on: https://chromium-review.googlesource.com/1131567Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarLuc Ferron <lucferron@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent b7c4f2b9
...@@ -595,8 +595,6 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node) ...@@ -595,8 +595,6 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
node->getLeft()->getType().getInterfaceBlock(); node->getLeft()->getType().getInterfaceBlock();
const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion(); const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
const TField *field = interfaceBlock->fields()[index->getIConst(0)]; const TField *field = interfaceBlock->fields()[index->getIConst(0)];
ASSERT(interfaceBlock->symbolType() == SymbolType::UserDefined ||
interfaceBlock->name() == "gl_PerVertex");
out << hashFieldName(field); out << hashFieldName(field);
visitChildren = false; visitChildren = false;
} }
......
...@@ -46,7 +46,7 @@ void TOutputVulkanGLSL::writeLayoutQualifier(TIntermTyped *variable) ...@@ -46,7 +46,7 @@ void TOutputVulkanGLSL::writeLayoutQualifier(TIntermTyped *variable)
bool needsCustomLayout = bool needsCustomLayout =
(type.getQualifier() == EvqAttribute || type.getQualifier() == EvqFragmentOut || (type.getQualifier() == EvqAttribute || type.getQualifier() == EvqFragmentOut ||
type.getQualifier() == EvqVertexIn || IsVarying(type.getQualifier()) || type.getQualifier() == EvqVertexIn || IsVarying(type.getQualifier()) ||
IsSampler(type.getBasicType())); IsSampler(type.getBasicType()) || type.isInterfaceBlock());
if (!NeedsToWriteLayoutQualifier(type) && !needsCustomLayout) if (!NeedsToWriteLayoutQualifier(type) && !needsCustomLayout)
{ {
...@@ -58,8 +58,6 @@ void TOutputVulkanGLSL::writeLayoutQualifier(TIntermTyped *variable) ...@@ -58,8 +58,6 @@ void TOutputVulkanGLSL::writeLayoutQualifier(TIntermTyped *variable)
// This isn't super clean, but it gets the job done. // This isn't super clean, but it gets the job done.
// See corresponding code in GlslangWrapper.cpp. // See corresponding code in GlslangWrapper.cpp.
// TODO(jmadill): Ensure declarations are separated.
TIntermSymbol *symbol = variable->getAsSymbolNode(); TIntermSymbol *symbol = variable->getAsSymbolNode();
ASSERT(symbol); ASSERT(symbol);
...@@ -99,9 +97,7 @@ void TOutputVulkanGLSL::writeQualifier(TQualifier qualifier, const TSymbol *symb ...@@ -99,9 +97,7 @@ void TOutputVulkanGLSL::writeQualifier(TQualifier qualifier, const TSymbol *symb
} }
TInfoSinkBase &out = objSink(); TInfoSinkBase &out = objSink();
out << "@@ QUALIFIER-"; out << "@@ QUALIFIER-" << symbol->name().data() << " @@ ";
out << symbol->name().data();
out << " @@ ";
} }
void TOutputVulkanGLSL::writeStructType(const TStructure *structure) void TOutputVulkanGLSL::writeStructType(const TStructure *structure)
...@@ -112,5 +108,4 @@ void TOutputVulkanGLSL::writeStructType(const TStructure *structure) ...@@ -112,5 +108,4 @@ void TOutputVulkanGLSL::writeStructType(const TStructure *structure)
objSink() << ";\n"; objSink() << ";\n";
} }
} }
} // namespace sh } // namespace sh
...@@ -256,6 +256,44 @@ void AppendVertexShaderDepthCorrectionToMain(TIntermBlock *root, TSymbolTable *s ...@@ -256,6 +256,44 @@ void AppendVertexShaderDepthCorrectionToMain(TIntermBlock *root, TSymbolTable *s
// Append the assignment as a statement at the end of the shader. // Append the assignment as a statement at the end of the shader.
RunAtTheEndOfShader(root, assignment, symbolTable); RunAtTheEndOfShader(root, assignment, symbolTable);
} }
// The AddDriverUniformsToShader operation adds an internal uniform block to a shader. The driver
// block is used to implement Vulkan-specific features and workarounds. Returns the driver uniforms
// variable.
const TVariable *AddDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable)
{
// This field list mirrors the structure of ContextVk::DriverUniforms.
TFieldList *driverFieldList = new TFieldList;
// Add a vec4 field "viewport" to the driver uniform fields.
TType *driverViewportType = new TType(EbtFloat, 4);
TField *driverViewportSize = new TField(driverViewportType, ImmutableString("viewport"),
TSourceLoc(), SymbolType::AngleInternal);
driverFieldList->push_back(driverViewportSize);
// Define a driver uniform block "ANGLEUniformBlock".
TLayoutQualifier driverLayoutQualifier = TLayoutQualifier::Create();
TInterfaceBlock *interfaceBlock =
new TInterfaceBlock(symbolTable, ImmutableString("ANGLEUniformBlock"), driverFieldList,
driverLayoutQualifier, SymbolType::AngleInternal);
// Make the inteface block into a declaration. Use instance name "ANGLEUniforms".
TType *interfaceBlockType = new TType(interfaceBlock, EvqUniform, driverLayoutQualifier);
TIntermDeclaration *driverUniformsDecl = new TIntermDeclaration;
TVariable *driverUniformsVar = new TVariable(symbolTable, ImmutableString("ANGLEUniforms"),
interfaceBlockType, SymbolType::AngleInternal);
TIntermSymbol *driverUniformsDeclarator = new TIntermSymbol(driverUniformsVar);
driverUniformsDecl->appendDeclarator(driverUniformsDeclarator);
// Insert the declarations before Main.
TIntermSequence *insertSequence = new TIntermSequence;
insertSequence->push_back(driverUniformsDecl);
size_t mainIndex = FindMainIndex(root);
root->insertChildNodes(mainIndex, *insertSequence);
return driverUniformsVar;
}
} // anonymous namespace } // anonymous namespace
TranslatorVulkan::TranslatorVulkan(sh::GLenum type, ShShaderSpec spec) TranslatorVulkan::TranslatorVulkan(sh::GLenum type, ShShaderSpec spec)
...@@ -315,6 +353,8 @@ void TranslatorVulkan::translate(TIntermBlock *root, ...@@ -315,6 +353,8 @@ void TranslatorVulkan::translate(TIntermBlock *root,
sink << "};\n"; sink << "};\n";
} }
AddDriverUniformsToShader(root, &getSymbolTable());
// Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData // Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData
// if it's core profile shaders and they are used. // if it's core profile shaders and they are used.
if (getShaderType() == GL_FRAGMENT_SHADER) if (getShaderType() == GL_FRAGMENT_SHADER)
......
...@@ -14,6 +14,21 @@ ...@@ -14,6 +14,21 @@
namespace sh namespace sh
{ {
size_t FindMainIndex(TIntermBlock *root)
{
const TIntermSequence &sequence = *root->getSequence();
for (size_t index = 0; index < sequence.size(); ++index)
{
TIntermNode *node = sequence[index];
TIntermFunctionDefinition *nodeFunction = node->getAsFunctionDefinition();
if (nodeFunction != nullptr && nodeFunction->getFunction()->isMain())
{
return index;
}
}
return std::numeric_limits<size_t>::max();
}
TIntermFunctionDefinition *FindMain(TIntermBlock *root) TIntermFunctionDefinition *FindMain(TIntermBlock *root)
{ {
for (TIntermNode *node : *root->getSequence()) for (TIntermNode *node : *root->getSequence())
......
...@@ -9,15 +9,16 @@ ...@@ -9,15 +9,16 @@
#ifndef COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_ #ifndef COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_
#define COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_ #define COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_
#include <cstddef>
namespace sh namespace sh
{ {
class TIntermBlock; class TIntermBlock;
class TIntermFunctionDefinition; class TIntermFunctionDefinition;
size_t FindMainIndex(TIntermBlock *root);
TIntermFunctionDefinition *FindMain(TIntermBlock *root); TIntermFunctionDefinition *FindMain(TIntermBlock *root);
TIntermBlock *FindMainBody(TIntermBlock *root); TIntermBlock *FindMainBody(TIntermBlock *root);
} // namespace sh } // namespace sh
#endif // COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_ #endif // COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_
\ No newline at end of file
...@@ -299,6 +299,15 @@ gl::LinkResult GlslangWrapper::linkProgram(const gl::Context *glContext, ...@@ -299,6 +299,15 @@ gl::LinkResult GlslangWrapper::linkProgram(const gl::Context *glContext,
} }
} }
// Substitute layout and qualifier strings for the driver uniforms block.
constexpr char kDriverBlockLayoutString[] = "set = 2, binding = 0";
constexpr char kDriverBlockName[] = "ANGLEUniforms";
InsertLayoutSpecifierString(&vertexSource, kDriverBlockName, kDriverBlockLayoutString);
InsertLayoutSpecifierString(&fragmentSource, kDriverBlockName, kDriverBlockLayoutString);
InsertQualifierSpecifierString(&vertexSource, kDriverBlockName, kUniformQualifier);
InsertQualifierSpecifierString(&fragmentSource, kDriverBlockName, kUniformQualifier);
std::array<const char *, 2> strings = {{vertexSource.c_str(), fragmentSource.c_str()}}; std::array<const char *, 2> strings = {{vertexSource.c_str(), fragmentSource.c_str()}};
std::array<int, 2> lengths = { std::array<int, 2> lengths = {
{static_cast<int>(vertexSource.length()), static_cast<int>(fragmentSource.length())}}; {static_cast<int>(vertexSource.length()), static_cast<int>(fragmentSource.length())}};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment