Commit c229ccfe by Shahbaz Youssefi Committed by Angle LUCI CQ

Vulkan: SPIR-V Gen: Handle gl_PerVertex

If not declared by the shader, default gl_PerVertex is now explicitly declared in AST prior to SPIR-V generation. The SPIR-V generation code then doesn't need to declare them magically. Bug: angleproject:4889 Change-Id: Icc593bc1ccc3162487bdbae7f66bc775d098778d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2905952 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 81db1a46
......@@ -170,6 +170,7 @@ angle_translator_sources = [
"src/compiler/translator/tree_ops/gl/mac/AddAndTrueToLoopCondition.h",
"src/compiler/translator/tree_ops/gl/mac/RewriteDoWhile.h",
"src/compiler/translator/tree_ops/gl/mac/UnfoldShortCircuitAST.h",
"src/compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.h",
"src/compiler/translator/tree_ops/vulkan/EarlyFragmentTestsOptimization.h",
"src/compiler/translator/tree_util/BuiltIn.h",
"src/compiler/translator/tree_util/BuiltIn_ESSL_autogen.h",
......@@ -317,6 +318,7 @@ angle_translator_lib_vulkan_sources = [
"src/compiler/translator/OutputVulkanGLSL.h",
"src/compiler/translator/TranslatorVulkan.cpp",
"src/compiler/translator/glslang_wrapper.cpp",
"src/compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.cpp",
"src/compiler/translator/tree_ops/vulkan/EarlyFragmentTestsOptimization.cpp",
"src/compiler/translator/tree_ops/vulkan/FlagSamplersWithTexelFetch.cpp",
"src/compiler/translator/tree_ops/vulkan/FlagSamplersWithTexelFetch.h",
......
......@@ -1053,6 +1053,7 @@ inline bool IsShaderIn(TQualifier qualifier)
case EvqTessEvaluationIn:
case EvqGeometryIn:
case EvqFragmentIn:
case EvqPerVertexIn:
case EvqAttribute:
case EvqVaryingIn:
case EvqSmoothIn:
......@@ -1076,6 +1077,7 @@ inline bool IsShaderOut(TQualifier qualifier)
case EvqTessEvaluationOut:
case EvqGeometryOut:
case EvqFragmentOut:
case EvqPerVertexOut:
case EvqVaryingOut:
case EvqSmoothOut:
case EvqFlatOut:
......
......@@ -83,7 +83,7 @@ const SpirvTypeData &SPIRVBuilder::getTypeData(const TType &type, TLayoutBlockSt
// from this. Default to std140.
ASSERT(spirvType.blockStorage == EbsUnspecified);
spirvType.blockStorage = type.getLayoutQualifier().blockStorage;
if (spirvType.blockStorage != EbsStd430)
if (!IsShaderIoBlock(type.getQualifier()) && spirvType.blockStorage != EbsStd430)
{
spirvType.blockStorage = EbsStd140;
}
......@@ -807,6 +807,39 @@ void SPIRVBuilder::addEntryPointInterfaceVariableId(spirv::IdRef id)
mEntryPointInterfaceList.push_back(id);
}
void SPIRVBuilder::writePerVertexBuiltIns(const TType &type, spirv::IdRef typeId)
{
ASSERT(type.isInterfaceBlock());
const TInterfaceBlock *block = type.getInterfaceBlock();
uint32_t fieldIndex = 0;
for (const TField *field : block->fields())
{
spv::BuiltIn decorationValue = spv::BuiltInPosition;
switch (field->type()->getQualifier())
{
case EvqPosition:
decorationValue = spv::BuiltInPosition;
break;
case EvqPointSize:
decorationValue = spv::BuiltInPointSize;
break;
case EvqClipDistance:
decorationValue = spv::BuiltInClipDistance;
break;
case EvqCullDistance:
decorationValue = spv::BuiltInCullDistance;
break;
default:
UNREACHABLE();
}
spirv::WriteMemberDecorate(&mSpirvDecorations, typeId, spirv::LiteralInteger(fieldIndex++),
spv::DecorationBuiltIn,
{spirv::LiteralInteger(decorationValue)});
}
}
void SPIRVBuilder::writeInterfaceVariableDecorations(const TType &type, spirv::IdRef variableId)
{
const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
......
......@@ -184,6 +184,7 @@ class SPIRVBuilder : angle::NonCopyable
void addExecutionMode(spv::ExecutionMode executionMode);
void setEntryPointId(spirv::IdRef id);
void addEntryPointInterfaceVariableId(spirv::IdRef id);
void writePerVertexBuiltIns(const TType &type, spirv::IdRef typeId);
void writeInterfaceVariableDecorations(const TType &type, spirv::IdRef variableId);
uint32_t calculateBaseAlignmentAndSize(const SpirvType &type, uint32_t *sizeInStorageBlockOut);
......
......@@ -337,6 +337,18 @@ bool OutputSPIRVTraverser::visitDeclaration(Visit visit, TIntermDeclaration *nod
{
// Add in and out variables to the list of interface variables.
mBuilder.addEntryPointInterfaceVariableId(variableId);
if (IsShaderIoBlock(type.getQualifier()) && type.isInterfaceBlock())
{
// For gl_PerVertex in particular, write the necessary BuiltIn decorations
if (type.getQualifier() == EvqPerVertexIn || type.getQualifier() == EvqPerVertexOut)
{
mBuilder.writePerVertexBuiltIns(type, typeId);
}
// I/O blocks are decorated with Block
spirv::WriteDecorate(mBuilder.getSpirvDecorations(), typeId, spv::DecorationBlock, {});
}
}
else if (type.getBasicType() == EbtInterfaceBlock)
{
......
......@@ -21,6 +21,7 @@
#include "compiler/translator/OutputVulkanGLSL.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/glslang_wrapper.h"
#include "compiler/translator/tree_ops/vulkan/DeclarePerVertexBlocks.h"
#include "compiler/translator/tree_ops/vulkan/FlagSamplersWithTexelFetch.h"
#include "compiler/translator/tree_ops/vulkan/MonomorphizeUnsupportedFunctionsInVulkanGLSL.h"
#include "compiler/translator/tree_ops/vulkan/RemoveAtomicCounterBuiltins.h"
......@@ -1341,6 +1342,13 @@ bool TranslatorVulkan::translate(TIntermBlock *root,
#if defined(ANGLE_ENABLE_DIRECT_SPIRV_GENERATION)
if ((compileOptions & SH_GENERATE_SPIRV_DIRECTLY) != 0 && getShaderType() == GL_VERTEX_SHADER)
{
// Declare the implicitly defined gl_PerVertex I/O blocks if not already. This will help
// SPIR-V generation treat them mostly like usual I/O blocks.
if (!DeclarePerVertexBlocks(this, root, &getSymbolTable()))
{
return false;
}
return OutputSPIRV(this, root, compileOptions);
}
#endif
......
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DeclarePerVertexBlocks: If gl_PerVertex is not already declared, it is declared and builts are
// turned into references into that I/O block.
//
#ifndef COMPILER_TRANSLATOR_TREEOPS_VULKAN_DECLAREPERVERTEXBLOCKS_H_
#define COMPILER_TRANSLATOR_TREEOPS_VULKAN_DECLAREPERVERTEXBLOCKS_H_
#include "common/angleutils.h"
namespace sh
{
class TCompiler;
class TIntermBlock;
class TSymbolTable;
ANGLE_NO_DISCARD bool DeclarePerVertexBlocks(TCompiler *compiler,
TIntermBlock *root,
TSymbolTable *symbolTable);
} // namespace sh
#endif // COMPILER_TRANSLATOR_TREEOPS_VULKAN_DECLAREPERVERTEXBLOCKS_H_
......@@ -42,9 +42,10 @@ class Traverser : public TIntermTraverser
if (type.isStructSpecifier() && type.getQualifier() == EvqUniform)
{
doReplacement(decl, declarator, type);
return false;
}
return false;
return true;
}
void visitSymbol(TIntermSymbol *symbol) override
......
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