Vulkan: SPIR-V Gen: Support multiview
Bug: angleproject:4889
Change-Id: Ibe66f53357473dbb4435af58775b524d83ed250b
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3052675
Reviewed-by: Tim Van Patten <timvp@google.com>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/compiler/translator/BuildSPIRV.cpp b/src/compiler/translator/BuildSPIRV.cpp
index 4ae20a7..844a342 100644
--- a/src/compiler/translator/BuildSPIRV.cpp
+++ b/src/compiler/translator/BuildSPIRV.cpp
@@ -1623,6 +1623,11 @@
mExecutionModes.set(executionMode);
}
+void SPIRVBuilder::addExtension(SPIRVExtensions extension)
+{
+ mExtensions.set(extension);
+}
+
void SPIRVBuilder::setEntryPointId(spirv::IdRef id)
{
ASSERT(!mEntryPointId.valid());
@@ -2038,7 +2043,8 @@
spirv::WriteCapability(&result, capability);
}
- // - OpExtension instructions (TODO: http://anglebug.com/4889)
+ // - OpExtension instructions
+ writeExtensions(&result);
// - OpExtInstImport
if (mExtInstImportIdStd.valid())
@@ -2062,13 +2068,14 @@
mEntryPointInterfaceList);
// - OpExecutionMode instructions
- generateExecutionModes(&result);
+ writeExecutionModes(&result);
- // - OpSource instruction.
+ // - OpSource and OpSourceExtension instructions.
//
// This is to support debuggers and capture/replay tools and isn't strictly necessary.
spirv::WriteSource(&result, spv::SourceLanguageGLSL, spirv::LiteralInteger(450), nullptr,
nullptr);
+ writeSourceExtensions(&result);
// Append the already generated sections in order
result.insert(result.end(), mSpirvDebug.begin(), mSpirvDebug.end());
@@ -2084,7 +2091,7 @@
return result;
}
-void SPIRVBuilder::generateExecutionModes(spirv::Blob *blob)
+void SPIRVBuilder::writeExecutionModes(spirv::Blob *blob)
{
switch (mShaderType)
{
@@ -2166,4 +2173,34 @@
}
}
+void SPIRVBuilder::writeExtensions(spirv::Blob *blob)
+{
+ for (SPIRVExtensions extension : mExtensions)
+ {
+ switch (extension)
+ {
+ case SPIRVExtensions::MultiviewOVR:
+ spirv::WriteExtension(blob, "SPV_KHR_multiview");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+}
+
+void SPIRVBuilder::writeSourceExtensions(spirv::Blob *blob)
+{
+ for (SPIRVExtensions extension : mExtensions)
+ {
+ switch (extension)
+ {
+ case SPIRVExtensions::MultiviewOVR:
+ spirv::WriteSourceExtension(blob, "GL_OVR_multiview");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+}
+
} // namespace sh
diff --git a/src/compiler/translator/BuildSPIRV.h b/src/compiler/translator/BuildSPIRV.h
index 064b84b..392d73b 100644
--- a/src/compiler/translator/BuildSPIRV.h
+++ b/src/compiler/translator/BuildSPIRV.h
@@ -10,6 +10,7 @@
#define COMPILER_TRANSLATOR_BUILDSPIRV_H_
#include "common/FixedVector.h"
+#include "common/PackedEnums.h"
#include "common/bitset_utils.h"
#include "common/hash_utils.h"
#include "common/spirv/spirv_instruction_builder_autogen.h"
@@ -274,6 +275,16 @@
bool isBreakable = false;
};
+// List of known extensions
+enum class SPIRVExtensions
+{
+ // GL_OVR_multiview / SPV_KHR_multiview
+ MultiviewOVR = 0,
+
+ InvalidEnum = 1,
+ EnumCount = 1,
+};
+
// Helper class to construct SPIR-V
class SPIRVBuilder : angle::NonCopyable
{
@@ -335,6 +346,7 @@
void addCapability(spv::Capability capability);
void addExecutionMode(spv::ExecutionMode executionMode);
+ void addExtension(SPIRVExtensions extension);
void setEntryPointId(spirv::IdRef id);
void addEntryPointInterfaceVariableId(spirv::IdRef id);
void writePerVertexBuiltIns(const TType &type, spirv::IdRef typeId);
@@ -432,7 +444,9 @@
uint32_t nextUnusedInputLocation(uint32_t consumedCount);
uint32_t nextUnusedOutputLocation(uint32_t consumedCount);
- void generateExecutionModes(spirv::Blob *blob);
+ void writeExecutionModes(spirv::Blob *blob);
+ void writeExtensions(spirv::Blob *blob);
+ void writeSourceExtensions(spirv::Blob *blob);
ANGLE_MAYBE_UNUSED TCompiler *mCompiler;
ShCompileOptions mCompileOptions;
@@ -446,6 +460,8 @@
// shader metadata, but some are only discovered while traversing the tree. Only the latter
// execution modes are stored here.
angle::BitSet<32> mExecutionModes;
+ // Extensions used by the shader.
+ angle::PackedEnumBitSet<SPIRVExtensions> mExtensions;
// The list of interface variables and the id of main() populated as the instructions are
// generated. Used for the OpEntryPoint instruction.
diff --git a/src/compiler/translator/OutputSPIRV.cpp b/src/compiler/translator/OutputSPIRV.cpp
index b00709f..246dc9b 100644
--- a/src/compiler/translator/OutputSPIRV.cpp
+++ b/src/compiler/translator/OutputSPIRV.cpp
@@ -459,6 +459,7 @@
case EvqLocalInvocationID:
case EvqGlobalInvocationID:
case EvqLocalInvocationIndex:
+ case EvqViewIDOVR:
return spv::StorageClassInput;
case EvqFragDepth:
@@ -634,6 +635,14 @@
builtInDecoration = spv::BuiltInLocalInvocationIndex;
break;
+ // Extensions
+ case EvqViewIDOVR:
+ name = "gl_ViewID_OVR";
+ builtInDecoration = spv::BuiltInViewIndex;
+ mBuilder.addCapability(spv::CapabilityMultiView);
+ mBuilder.addExtension(SPIRVExtensions::MultiviewOVR);
+ break;
+
default:
UNREACHABLE();
}