2
0
Эх сурвалжийг харах

[spirv] Cleanup of cl option handling for SPIRV. (#1521)

Ehsan 7 жил өмнө
parent
commit
a2bb5d400e

+ 3 - 20
include/dxc/Support/HLSLOptions.h

@@ -18,6 +18,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Option/ArgList.h"
 #include "dxc/dxcapi.h"
+#include "dxc/Support/SPIRVOptions.h"
 
 namespace llvm {
 namespace opt {
@@ -160,26 +161,8 @@ public:
 
   // SPIRV Change Starts
 #ifdef ENABLE_SPIRV_CODEGEN
-  bool GenSPIRV;                           // OPT_spirv
-  bool VkInvertY;                          // OPT_fvk_invert_y
-  bool VkInvertW;                          // OPT_fvk_use_dx_position_w
-  bool VkUseGlLayout;                      // OPT_fvk_use_gl_layout
-  bool VkUseDxLayout;                      // OPT_fvk_use_dx_layout
-  bool SpvEnableReflect;                   // OPT_fspv_reflect
-  bool VkNoWarnIgnoredFeatures;            // OPT_Wno_vk_ignored_features
-  bool SpvDebugFile;                       // OPT_fspv_debug
-  bool SpvDebugSource;                     // OPT_fspv_debug
-  bool SpvDebugLine;                       // OPT_fspv_debug
-  bool SpvDebugTool;                       // OPT_fspv_debug
-  llvm::StringRef VkStageIoOrder;          // OPT_fvk_stage_io_order
-  llvm::SmallVector<int32_t, 4> VkBShift;  // OPT_fvk_b_shift
-  llvm::SmallVector<int32_t, 4> VkTShift;  // OPT_fvk_t_shift
-  llvm::SmallVector<int32_t, 4> VkSShift;  // OPT_fvk_s_shift
-  llvm::SmallVector<int32_t, 4> VkUShift;  // OPT_fvk_u_shift
-  std::vector<std::string> VkBindRegister; // OPT_fvk_bind_register
-  llvm::SmallVector<llvm::StringRef, 4> SpvExtensions; // OPT_fspv_extension
-  llvm::StringRef SpvTargetEnv;                        // OPT_fspv_target_env
-  llvm::SmallVector<llvm::StringRef, 4> SpvOconfig;    // OPT_Oconfig
+  bool GenSPIRV;                    // OPT_spirv
+  clang::spirv::SpirvCodeGenOptions SpirvOptions; // All SPIR-V CodeGen-related options
 #endif
   // SPIRV Change Ends
 };

+ 33 - 30
tools/clang/include/clang/SPIRV/EmitSPIRVOptions.h → include/dxc/Support/SPIRVOptions.h

@@ -1,4 +1,4 @@
-//===-- EmitSPIRVOptions.h - Options for SPIR-V CodeGen ---------*- C++ -*-===//
+//===------- SPIRVOptions.h -------------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -6,19 +6,24 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SPIRV_EMITSPIRVOPTIONS_H
-#define LLVM_CLANG_SPIRV_EMITSPIRVOPTIONS_H
+//
+//  This file outlines the command-line options used by SPIR-V CodeGen.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SPIRV_OPTIONS_H
+#define LLVM_SPIRV_OPTIONS_H
 
-#include <string>
-#include <vector>
+#ifdef ENABLE_SPIRV_CODEGEN
 
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Option/ArgList.h"
 
 namespace clang {
 namespace spirv {
-/// Memory layout rules
-enum class LayoutRule {
+
+enum class SpirvLayoutRule {
   Void,
   GLSLStd140,
   GLSLStd430,
@@ -27,44 +32,42 @@ enum class LayoutRule {
   FxcCTBuffer,       // fxc.exe layout rule for cbuffer/tbuffer
   FxcSBuffer,        // fxc.exe layout rule for structured buffers
 };
-} // namespace spirv
 
-/// Structs for controlling behaviors of SPIR-V codegen.
-struct EmitSPIRVOptions {
+struct SpirvCodeGenOptions {
   /// Disable legalization and optimization and emit raw SPIR-V
   bool codeGenHighLevel;
+  bool debugInfoFile;
+  bool debugInfoLine;
+  bool debugInfoSource;
+  bool debugInfoTool;
   bool defaultRowMajor;
   bool disableValidation;
-  bool invertY; // Additive inverse
-  bool invertW; // Multiplicative inverse
-  bool useGlLayout;
-  bool useDxLayout;
   bool enable16BitTypes;
   bool enableReflect;
-  bool debugInfoFile;
-  bool debugInfoSource;
-  bool debugInfoLine;
-  bool debugInfoTool;
+  bool invertY; // Additive inverse
+  bool invertW; // Multiplicative inverse
   bool noWarnIgnoredFeatures;
+  bool useDxLayout;
+  bool useGlLayout;
+  SpirvLayoutRule cBufferLayoutRule;
+  SpirvLayoutRule sBufferLayoutRule;
+  SpirvLayoutRule tBufferLayoutRule;
   llvm::StringRef stageIoOrder;
+  llvm::StringRef targetEnv;
   llvm::SmallVector<int32_t, 4> bShift;
-  llvm::SmallVector<int32_t, 4> tShift;
   llvm::SmallVector<int32_t, 4> sShift;
+  llvm::SmallVector<int32_t, 4> tShift;
   llvm::SmallVector<int32_t, 4> uShift;
-  std::vector<std::string> bindRegister;
   llvm::SmallVector<llvm::StringRef, 4> allowedExtensions;
-  llvm::StringRef targetEnv;
-  spirv::LayoutRule cBufferLayoutRule;
-  spirv::LayoutRule tBufferLayoutRule;
-  spirv::LayoutRule sBufferLayoutRule;
   llvm::SmallVector<llvm::StringRef, 4> optConfig;
+  std::vector<std::string> bindRegister;
 
   // String representation of all command line options.
   std::string clOptions;
-
-  /// Initializes dependent fields appropriately
-  void Initialize();
 };
-} // end namespace clang
 
-#endif
+} // namespace spirv
+} // namespace clang
+
+#endif // ENABLE_SPIRV_CODEGEN
+#endif // LLVM_SPIRV_OPTIONS_H

+ 29 - 28
lib/DxcSupport/HLSLOptions.cpp

@@ -557,47 +557,48 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
   // SPIRV Change Starts
 #ifdef ENABLE_SPIRV_CODEGEN
   opts.GenSPIRV = Args.hasFlag(OPT_spirv, OPT_INVALID, false);
-  opts.VkInvertY = Args.hasFlag(OPT_fvk_invert_y, OPT_INVALID, false);
-  opts.VkInvertW = Args.hasFlag(OPT_fvk_use_dx_position_w, OPT_INVALID, false);
-  opts.VkUseGlLayout = Args.hasFlag(OPT_fvk_use_gl_layout, OPT_INVALID, false);
-  opts.VkUseDxLayout = Args.hasFlag(OPT_fvk_use_dx_layout, OPT_INVALID, false);
-  opts.SpvEnableReflect = Args.hasFlag(OPT_fspv_reflect, OPT_INVALID, false);
-  opts.VkNoWarnIgnoredFeatures = Args.hasFlag(OPT_Wno_vk_ignored_features, OPT_INVALID, false);
-
-  if (!handleVkShiftArgs(Args, OPT_fvk_b_shift, "b", &opts.VkBShift, errors) ||
-      !handleVkShiftArgs(Args, OPT_fvk_t_shift, "t", &opts.VkTShift, errors) ||
-      !handleVkShiftArgs(Args, OPT_fvk_s_shift, "s", &opts.VkSShift, errors) ||
-      !handleVkShiftArgs(Args, OPT_fvk_u_shift, "u", &opts.VkUShift, errors))
+  opts.SpirvOptions.invertY = Args.hasFlag(OPT_fvk_invert_y, OPT_INVALID, false);
+  opts.SpirvOptions.invertW = Args.hasFlag(OPT_fvk_use_dx_position_w, OPT_INVALID, false);
+  opts.SpirvOptions.useGlLayout = Args.hasFlag(OPT_fvk_use_gl_layout, OPT_INVALID, false);
+  opts.SpirvOptions.useDxLayout = Args.hasFlag(OPT_fvk_use_dx_layout, OPT_INVALID, false);
+  opts.SpirvOptions.enableReflect = Args.hasFlag(OPT_fspv_reflect, OPT_INVALID, false);
+  opts.SpirvOptions.noWarnIgnoredFeatures = Args.hasFlag(OPT_Wno_vk_ignored_features, OPT_INVALID, false);
+
+  if (!handleVkShiftArgs(Args, OPT_fvk_b_shift, "b", &opts.SpirvOptions.bShift, errors) ||
+      !handleVkShiftArgs(Args, OPT_fvk_t_shift, "t", &opts.SpirvOptions.tShift, errors) ||
+      !handleVkShiftArgs(Args, OPT_fvk_s_shift, "s", &opts.SpirvOptions.sShift, errors) ||
+      !handleVkShiftArgs(Args, OPT_fvk_u_shift, "u", &opts.SpirvOptions.uShift, errors))
     return 1;
 
-  opts.VkBindRegister = Args.getAllArgValues(OPT_fvk_bind_register);
-
-  opts.VkStageIoOrder = Args.getLastArgValue(OPT_fvk_stage_io_order_EQ, "decl");
-  if (opts.VkStageIoOrder != "alpha" && opts.VkStageIoOrder != "decl") {
+  opts.SpirvOptions.bindRegister = Args.getAllArgValues(OPT_fvk_bind_register);
+  opts.SpirvOptions.stageIoOrder = Args.getLastArgValue(OPT_fvk_stage_io_order_EQ, "decl");
+  if (opts.SpirvOptions.stageIoOrder != "alpha" && opts.SpirvOptions.stageIoOrder != "decl") {
     errors << "unknown Vulkan stage I/O location assignment order: "
-           << opts.VkStageIoOrder;
+           << opts.SpirvOptions.stageIoOrder;
     return 1;
   }
 
   for (const Arg *A : Args.filtered(OPT_fspv_extension_EQ)) {
-    opts.SpvExtensions.push_back(A->getValue());
+    opts.SpirvOptions.allowedExtensions.push_back(A->getValue());
   }
 
-  opts.SpvDebugFile = opts.SpvDebugSource = false;
-  opts.SpvDebugLine = opts.SpvDebugTool = false;
+  opts.SpirvOptions.debugInfoFile = opts.SpirvOptions.debugInfoSource = false;
+  opts.SpirvOptions.debugInfoLine = opts.SpirvOptions.debugInfoTool = false;
   if (Args.hasArg(OPT_fspv_debug_EQ)) {
     opts.DebugInfo = true;
     for (const Arg *A : Args.filtered(OPT_fspv_debug_EQ)) {
       const llvm::StringRef v = A->getValue();
       if (v == "file") {
-        opts.SpvDebugFile = true;
+        opts.SpirvOptions.debugInfoFile = true;
       } else if (v == "source") {
-        opts.SpvDebugFile = opts.SpvDebugSource = true;
+        opts.SpirvOptions.debugInfoFile = true;
+        opts.SpirvOptions.debugInfoSource = true;
       } else if (v == "line") {
-        opts.SpvDebugFile = opts.SpvDebugSource = true;
-        opts.SpvDebugLine = true;
+        opts.SpirvOptions.debugInfoFile = true;
+        opts.SpirvOptions.debugInfoSource = true;
+        opts.SpirvOptions.debugInfoLine = true;
       } else if (v == "tool") {
-        opts.SpvDebugTool = true;
+        opts.SpirvOptions.debugInfoTool = true;
       } else {
         errors << "unknown SPIR-V debug info control parameter: " << v;
         return 1;
@@ -605,11 +606,11 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
     }
   } else if (opts.DebugInfo) {
     // By default turn on all categories
-    opts.SpvDebugFile = opts.SpvDebugSource = true;
-    opts.SpvDebugLine = opts.SpvDebugTool = true;
+    opts.SpirvOptions.debugInfoFile = opts.SpirvOptions.debugInfoSource = true;
+    opts.SpirvOptions.debugInfoLine = opts.SpirvOptions.debugInfoTool = true;
   }
 
-  opts.SpvTargetEnv = Args.getLastArgValue(OPT_fspv_target_env_EQ, "vulkan1.0");
+  opts.SpirvOptions.targetEnv = Args.getLastArgValue(OPT_fspv_target_env_EQ, "vulkan1.0");
 
   // Handle -Oconfig=<comma-separated-list> option.
   uint32_t numOconfigs = 0;
@@ -624,7 +625,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
       return 1;
     }
     for (const auto v : A->getValues()) {
-      opts.SpvOconfig.push_back(v);
+      opts.SpirvOptions.optConfig.push_back(v);
     }
   }
 

+ 8 - 0
tools/clang/include/clang/Frontend/CodeGenOptions.h

@@ -20,6 +20,7 @@
 #include <string>
 #include <vector>
 #include "dxc/HLSL/HLSLExtensionsCodegenHelper.h" // HLSL change
+#include "dxc/Support/SPIRVOptions.h" // SPIR-V Change
 
 namespace clang {
 
@@ -201,6 +202,13 @@ public:
   /// denormalized number mode ("ieee" for default)
   hlsl::DXIL::Float32DenormMode HLSLFloat32DenormMode;
   // HLSL Change Ends
+
+  // SPIRV Change Starts
+#ifdef ENABLE_SPIRV_CODEGEN
+  clang::spirv::SpirvCodeGenOptions SpirvOptions;
+#endif
+  // SPIRV Change Ends
+
   /// Regular expression to select optimizations for which we should enable
   /// optimization remarks. Transformation passes whose name matches this
   /// expression (and support this feature), will emit a diagnostic

+ 1 - 6
tools/clang/include/clang/SPIRV/EmitSPIRVAction.h

@@ -11,20 +11,15 @@
 
 #include "clang/Frontend/FrontendAction.h"
 
-#include "clang/SPIRV/EmitSPIRVOptions.h"
-
 namespace clang {
 
 class EmitSPIRVAction : public ASTFrontendAction {
 public:
-  EmitSPIRVAction(const EmitSPIRVOptions &opts) : options(opts) {}
+  EmitSPIRVAction() {}
 
 protected:
   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
                                                  StringRef InFile) override;
-
-private:
-  EmitSPIRVOptions options;
 };
 
 } // end namespace clang

+ 2 - 3
tools/clang/include/clang/SPIRV/FeatureManager.h

@@ -19,11 +19,10 @@
 
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceLocation.h"
+#include "dxc/Support/SPIRVOptions.h"
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/StringRef.h"
 
-#include "EmitSPIRVOptions.h"
-
 namespace clang {
 namespace spirv {
 
@@ -48,7 +47,7 @@ enum class Extension {
 /// The class for handling SPIR-V version and extension requests.
 class FeatureManager {
 public:
-  FeatureManager(DiagnosticsEngine &de, const EmitSPIRVOptions &);
+  FeatureManager(DiagnosticsEngine &de, const SpirvCodeGenOptions &);
 
   /// Allows the given extension to be used in CodeGen.
   bool allowExtension(llvm::StringRef);

+ 4 - 4
tools/clang/include/clang/SPIRV/ModuleBuilder.h

@@ -37,7 +37,7 @@ class ModuleBuilder {
 public:
   /// \brief Constructs a ModuleBuilder with the given SPIR-V context.
   ModuleBuilder(SPIRVContext *, FeatureManager *features,
-                const EmitSPIRVOptions &opts);
+                const SpirvCodeGenOptions &opts);
 
   /// \brief Returns the associated SPIRVContext.
   inline SPIRVContext *getSPIRVContext();
@@ -509,9 +509,9 @@ private:
       uint32_t sample, uint32_t minLod,
       llvm::SmallVectorImpl<uint32_t> *orderedParams);
 
-  SPIRVContext &theContext;             ///< The SPIR-V context.
-  FeatureManager *featureManager;       ///< SPIR-V version/extension manager.
-  const EmitSPIRVOptions &spirvOptions; ///< Command line options.
+  SPIRVContext &theContext;       ///< The SPIR-V context.
+  FeatureManager *featureManager; ///< SPIR-V version/extension manager.
+  const SpirvCodeGenOptions &spirvOptions; ///< Command line options.
 
   SPIRVModule theModule;                 ///< The module under building.
   std::unique_ptr<Function> theFunction; ///< The function under building.

+ 4 - 4
tools/clang/include/clang/SPIRV/Structure.h

@@ -26,7 +26,6 @@
 
 #include "spirv/unified1/spirv.hpp11"
 #include "clang/SPIRV/Constant.h"
-#include "clang/SPIRV/EmitSPIRVOptions.h"
 #include "clang/SPIRV/InstBuilder.h"
 #include "clang/SPIRV/Type.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -35,6 +34,7 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "dxc/Support/SPIRVOptions.h"
 
 namespace clang {
 namespace spirv {
@@ -273,7 +273,7 @@ struct TypeIdPair {
 class SPIRVModule {
 public:
   /// \brief Default constructs an empty SPIR-V module.
-  inline SPIRVModule(const EmitSPIRVOptions &options);
+  inline SPIRVModule(const SpirvCodeGenOptions &options);
 
   // Disable copy constructor/assignment
   SPIRVModule(const SPIRVModule &) = delete;
@@ -329,7 +329,7 @@ public:
   inline uint32_t getExtInstSetId(llvm::StringRef setName);
 
 private:
-  const EmitSPIRVOptions &spirvOptions;
+  const SpirvCodeGenOptions &spirvOptions;
 
   Header header; ///< SPIR-V module header.
   llvm::SetVector<spv::Capability> capabilities;
@@ -457,7 +457,7 @@ TypeIdPair::TypeIdPair(const Type &ty, uint32_t id) : type(ty), resultId(id) {}
 
 // === Module inline implementations ===
 
-SPIRVModule::SPIRVModule(const EmitSPIRVOptions &options)
+SPIRVModule::SPIRVModule(const SpirvCodeGenOptions &options)
     : spirvOptions(options), addressingModel(llvm::None),
       memoryModel(llvm::None), shaderModelVersion(0), sourceFileNameId(0) {}
 

+ 0 - 1
tools/clang/lib/SPIRV/CMakeLists.txt

@@ -8,7 +8,6 @@ add_clang_library(clangSPIRV
   DeclResultIdMapper.cpp
   Decoration.cpp
   EmitSPIRVAction.cpp
-  EmitSPIRVOptions.cpp
   FeatureManager.cpp
   GlPerVertex.cpp
   InitListHandler.cpp

+ 3 - 3
tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

@@ -372,7 +372,7 @@ SpirvEvalInfo DeclResultIdMapper::createFileVar(const VarDecl *var,
 
 SpirvEvalInfo DeclResultIdMapper::createExternVar(const VarDecl *var) {
   auto storageClass = spv::StorageClass::UniformConstant;
-  auto rule = LayoutRule::Void;
+  auto rule = SpirvLayoutRule::Void;
   bool isACRWSBuffer = false; // Whether is {Append|Consume|RW}StructuredBuffer
 
   if (var->getAttr<HLSLGroupSharedAttr>()) {
@@ -454,7 +454,7 @@ SpirvEvalInfo DeclResultIdMapper::createExternVar(const VarDecl *var) {
 
 uint32_t DeclResultIdMapper::getMatrixStructType(const VarDecl *matVar,
                                                  spv::StorageClass sc,
-                                                 LayoutRule rule) {
+                                                 SpirvLayoutRule rule) {
   const auto matType = matVar->getType();
   assert(TypeTranslator::isMxNMatrix(matType));
 
@@ -492,7 +492,7 @@ uint32_t DeclResultIdMapper::createStructOrStructArrayVarOfExplicitLayout(
   const bool forPC = usageKind == ContextUsageKind::PushConstant;
 
   auto &context = *theBuilder.getSPIRVContext();
-  const LayoutRule layoutRule =
+  const SpirvLayoutRule layoutRule =
       (forCBuffer || forGlobals)
           ? spirvOptions.cBufferLayoutRule
           : (forTBuffer ? spirvOptions.tBufferLayoutRule

+ 5 - 5
tools/clang/lib/SPIRV/DeclResultIdMapper.h

@@ -16,9 +16,9 @@
 #include "dxc/HLSL/DxilSemantic.h"
 #include "dxc/HLSL/DxilShaderModel.h"
 #include "dxc/HLSL/DxilSigPoint.h"
+#include "dxc/Support/SPIRVOptions.h"
 #include "spirv/unified1/spirv.hpp11"
 #include "clang/AST/Attr.h"
-#include "clang/SPIRV/EmitSPIRVOptions.h"
 #include "clang/SPIRV/FeatureManager.h"
 #include "clang/SPIRV/ModuleBuilder.h"
 #include "llvm/ADT/DenseMap.h"
@@ -259,7 +259,7 @@ public:
   inline DeclResultIdMapper(const hlsl::ShaderModel &stage, ASTContext &context,
                             ModuleBuilder &builder, TypeTranslator &translator,
                             FeatureManager &features,
-                            const EmitSPIRVOptions &spirvOptions);
+                            const SpirvCodeGenOptions &spirvOptions);
 
   /// \brief Returns the <result-id> for a SPIR-V builtin variable.
   uint32_t getBuiltinVar(spv::BuiltIn builtIn);
@@ -511,7 +511,7 @@ private:
   /// \brief Wraps the given matrix type with a struct and returns the struct
   /// type's <result-id>.
   uint32_t getMatrixStructType(const VarDecl *matVar, spv::StorageClass,
-                               LayoutRule);
+                               SpirvLayoutRule);
 
   /// \brief An enum class for representing what the DeclContext is used for
   enum class ContextUsageKind {
@@ -628,7 +628,7 @@ private:
 private:
   const hlsl::ShaderModel &shaderModel;
   ModuleBuilder &theBuilder;
-  const EmitSPIRVOptions &spirvOptions;
+  const SpirvCodeGenOptions &spirvOptions;
   ASTContext &astContext;
   DiagnosticsEngine &diags;
 
@@ -747,7 +747,7 @@ DeclResultIdMapper::DeclResultIdMapper(const hlsl::ShaderModel &model,
                                        ModuleBuilder &builder,
                                        TypeTranslator &translator,
                                        FeatureManager &features,
-                                       const EmitSPIRVOptions &options)
+                                       const SpirvCodeGenOptions &options)
     : shaderModel(model), theBuilder(builder), spirvOptions(options),
       astContext(context), diags(context.getDiagnostics()),
       typeTranslator(translator), entryFunctionId(0), laneCountBuiltinId(0),

+ 1 - 1
tools/clang/lib/SPIRV/EmitSPIRVAction.cpp

@@ -18,6 +18,6 @@ namespace clang {
 
 std::unique_ptr<ASTConsumer>
 EmitSPIRVAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
-  return llvm::make_unique<spirv::SPIRVEmitter>(CI, options);
+  return llvm::make_unique<spirv::SPIRVEmitter>(CI);
 }
 } // end namespace clang

+ 0 - 29
tools/clang/lib/SPIRV/EmitSPIRVOptions.cpp

@@ -1,29 +0,0 @@
-//===-- EmitSPIRVOptions.cpp - Options for SPIR-V CodeGen -------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include "clang/SPIRV/EmitSPIRVOptions.h"
-
-namespace clang {
-
-void EmitSPIRVOptions::Initialize() {
-  if (useDxLayout) {
-    cBufferLayoutRule = spirv::LayoutRule::FxcCTBuffer;
-    tBufferLayoutRule = spirv::LayoutRule::FxcCTBuffer;
-    sBufferLayoutRule = spirv::LayoutRule::FxcSBuffer;
-  } else if (useGlLayout) {
-    cBufferLayoutRule = spirv::LayoutRule::GLSLStd140;
-    tBufferLayoutRule = spirv::LayoutRule::GLSLStd430;
-    sBufferLayoutRule = spirv::LayoutRule::GLSLStd430;
-  } else {
-    cBufferLayoutRule = spirv::LayoutRule::RelaxedGLSLStd140;
-    tBufferLayoutRule = spirv::LayoutRule::RelaxedGLSLStd430;
-    sBufferLayoutRule = spirv::LayoutRule::RelaxedGLSLStd430;
-  }
-}
-
-} // end namespace clang

+ 1 - 1
tools/clang/lib/SPIRV/FeatureManager.cpp

@@ -16,7 +16,7 @@ namespace clang {
 namespace spirv {
 
 FeatureManager::FeatureManager(DiagnosticsEngine &de,
-                               const EmitSPIRVOptions &opts)
+                               const SpirvCodeGenOptions &opts)
     : diags(de) {
   allowedExtensions.resize(static_cast<unsigned>(Extension::Unknown) + 1);
 

+ 1 - 1
tools/clang/lib/SPIRV/ModuleBuilder.cpp

@@ -18,7 +18,7 @@ namespace clang {
 namespace spirv {
 
 ModuleBuilder::ModuleBuilder(SPIRVContext *C, FeatureManager *features,
-                             const EmitSPIRVOptions &opts)
+                             const SpirvCodeGenOptions &opts)
     : theContext(*C), featureManager(features), spirvOptions(opts),
       theModule(opts), theFunction(nullptr), insertPoint(nullptr),
       instBuilder(nullptr), glslExtSetId(0) {

+ 33 - 20
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -589,17 +589,18 @@ spv::Capability getNonUniformCapability(QualType type) {
 
 } // namespace
 
-SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci, EmitSPIRVOptions &options)
+SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci)
     : theCompilerInstance(ci), astContext(ci.getASTContext()),
-      diags(ci.getDiagnostics()), spirvOptions(options),
+      diags(ci.getDiagnostics()),
+      spirvOptions(ci.getCodeGenOpts().SpirvOptions),
       entryFunctionName(ci.getCodeGenOpts().HLSLEntryFunction),
       shaderModel(*hlsl::ShaderModel::GetByName(
           ci.getCodeGenOpts().HLSLProfile.c_str())),
-      theContext(), featureManager(diags, options),
-      theBuilder(&theContext, &featureManager, options),
-      typeTranslator(astContext, theBuilder, diags, options),
+      theContext(), featureManager(diags, spirvOptions),
+      theBuilder(&theContext, &featureManager, spirvOptions),
+      typeTranslator(astContext, theBuilder, diags, spirvOptions),
       declIdMapper(shaderModel, astContext, theBuilder, typeTranslator,
-                   featureManager, options),
+                   featureManager, spirvOptions),
       entryFunctionId(0), curFunction(nullptr), curThis(0),
       seenPushConstantAt(), isSpecConstantMode(false),
       foundNonUniformResourceIndex(false), needsLegalization(false),
@@ -607,15 +608,27 @@ SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci, EmitSPIRVOptions &options)
   if (shaderModel.GetKind() == hlsl::ShaderModel::Kind::Invalid)
     emitError("unknown shader module: %0", {}) << shaderModel.GetName();
 
-  if (options.invertY && !shaderModel.IsVS() && !shaderModel.IsDS() &&
+  if (spirvOptions.invertY && !shaderModel.IsVS() && !shaderModel.IsDS() &&
       !shaderModel.IsGS())
     emitError("-fvk-invert-y can only be used in VS/DS/GS", {});
 
-  if (options.useGlLayout && options.useDxLayout)
+  if (spirvOptions.useGlLayout && spirvOptions.useDxLayout)
     emitError("cannot specify both -fvk-use-dx-layout and -fvk-use-gl-layout",
               {});
 
-  options.Initialize();
+  if (spirvOptions.useDxLayout) {
+    spirvOptions.cBufferLayoutRule = SpirvLayoutRule::FxcCTBuffer;
+    spirvOptions.tBufferLayoutRule = SpirvLayoutRule::FxcCTBuffer;
+    spirvOptions.sBufferLayoutRule = SpirvLayoutRule::FxcSBuffer;
+  } else if (spirvOptions.useGlLayout) {
+    spirvOptions.cBufferLayoutRule = SpirvLayoutRule::GLSLStd140;
+    spirvOptions.tBufferLayoutRule = SpirvLayoutRule::GLSLStd430;
+    spirvOptions.sBufferLayoutRule = SpirvLayoutRule::GLSLStd430;
+  } else {
+    spirvOptions.cBufferLayoutRule = SpirvLayoutRule::RelaxedGLSLStd140;
+    spirvOptions.tBufferLayoutRule = SpirvLayoutRule::RelaxedGLSLStd430;
+    spirvOptions.sBufferLayoutRule = SpirvLayoutRule::RelaxedGLSLStd430;
+  }
 
   // Set shader module version
   theBuilder.setShaderModelVersion(shaderModel.GetMajor(),
@@ -623,7 +636,7 @@ SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci, EmitSPIRVOptions &options)
 
   // Set debug info
   const auto &inputFiles = ci.getFrontendOpts().Inputs;
-  if (options.debugInfoFile && !inputFiles.empty()) {
+  if (spirvOptions.debugInfoFile && !inputFiles.empty()) {
     // File name
     mainSourceFileId = theContext.takeNextId();
     theBuilder.setSourceFileName(mainSourceFileId,
@@ -939,7 +952,7 @@ SpirvEvalInfo SPIRVEmitter::loadIfGLValue(const Expr *expr,
   // the uint, we should perform a comparison.
   {
     uint32_t vecSize = 1, numRows = 0, numCols = 0;
-    if (info.getLayoutRule() != LayoutRule::Void &&
+    if (info.getLayoutRule() != SpirvLayoutRule::Void &&
         isBoolOrVecMatOfBoolType(expr->getType())) {
       const auto exprType = expr->getType();
       QualType uintType = astContext.UnsignedIntTy;
@@ -978,7 +991,7 @@ SpirvEvalInfo SPIRVEmitter::loadIfGLValue(const Expr *expr,
       }
       // Now that it is converted to Bool, it has no layout rule.
       // This result-id should be evaluated as bool from here on out.
-      info.setLayoutRule(LayoutRule::Void);
+      info.setLayoutRule(SpirvLayoutRule::Void);
     }
   }
 
@@ -4528,7 +4541,7 @@ SPIRVEmitter::doExtMatrixElementExpr(const ExtMatrixElementExpr *expr) {
   // Note: Special-case: Booleans have no physical layout, and therefore when
   // layout is required booleans are represented as unsigned integers.
   // Therefore, after loading the uint we should convert it boolean.
-  if (elemType->isBooleanType() && layoutRule != LayoutRule::Void) {
+  if (elemType->isBooleanType() && layoutRule != SpirvLayoutRule::Void) {
     const auto fromType =
         size == 1 ? astContext.UnsignedIntTy
                   : astContext.getExtVectorType(astContext.UnsignedIntTy, size);
@@ -4592,7 +4605,7 @@ SPIRVEmitter::doHLSLVectorElementExpr(const HLSLVectorElementExpr *expr) {
       // Special-case: Booleans in SPIR-V do not have a physical layout. Uint is
       // used to represent them when layout is required.
       if (expr->getType()->isBooleanType() &&
-          baseInfo.getLayoutRule() != LayoutRule::Void)
+          baseInfo.getLayoutRule() != SpirvLayoutRule::Void)
         result =
             castToBool(result, astContext.UnsignedIntTy, astContext.BoolTy);
       return baseInfo.setResultId(result);
@@ -4907,7 +4920,7 @@ void SPIRVEmitter::storeValue(const SpirvEvalInfo &lhsPtr,
     // is used to represent booleans when layout is required. In such cases,
     // we should cast the boolean to uint before creating OpStore.
     if (isBoolOrVecOfBoolType(lhsValType) &&
-        lhsPtr.getLayoutRule() != LayoutRule::Void) {
+        lhsPtr.getLayoutRule() != SpirvLayoutRule::Void) {
       uint32_t vecSize = 1;
       const bool isVec =
           TypeTranslator::isVectorType(lhsValType, nullptr, &vecSize);
@@ -5001,7 +5014,7 @@ void SPIRVEmitter::storeValue(const SpirvEvalInfo &lhsPtr,
 
 uint32_t SPIRVEmitter::reconstructValue(const SpirvEvalInfo &srcVal,
                                         const QualType valType,
-                                        LayoutRule dstLR) {
+                                        SpirvLayoutRule dstLR) {
   // Lambda for casting scalar or vector of bool<-->uint in cases where one side
   // of the reconstruction (lhs or rhs) has a layout rule.
   const auto handleBooleanLayout = [this, &srcVal, dstLR](uint32_t val,
@@ -5010,15 +5023,15 @@ uint32_t SPIRVEmitter::reconstructValue(const SpirvEvalInfo &srcVal,
     if (!isBoolOrVecOfBoolType(valType))
       return val;
 
-    LayoutRule srcLR = srcVal.getLayoutRule();
+    SpirvLayoutRule srcLR = srcVal.getLayoutRule();
     // Source value has a layout rule, and has therefore been represented
     // as a uint. Cast it to boolean before using.
     bool shouldCastToBool =
-        srcLR != LayoutRule::Void && dstLR == LayoutRule::Void;
+        srcLR != SpirvLayoutRule::Void && dstLR == SpirvLayoutRule::Void;
     // Destination has a layout rule, and should therefore be represented
     // as a uint. Cast to uint before using.
     bool shouldCastToUint =
-        srcLR == LayoutRule::Void && dstLR != LayoutRule::Void;
+        srcLR == SpirvLayoutRule::Void && dstLR != SpirvLayoutRule::Void;
     // No boolean layout issues to take care of.
     if (!shouldCastToBool && !shouldCastToUint)
       return val;
@@ -6127,7 +6140,7 @@ SpirvEvalInfo &SPIRVEmitter::turnIntoElementPtr(
     auto varName = TypeTranslator::getName(baseType);
     const auto var = createTemporaryVar(baseType, varName, base);
     base.setResultId(var)
-        .setLayoutRule(LayoutRule::Void)
+        .setLayoutRule(SpirvLayoutRule::Void)
         .setStorageClass(spv::StorageClass::Function);
   }
 

+ 3 - 4
tools/clang/lib/SPIRV/SPIRVEmitter.h

@@ -27,7 +27,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Frontend/CompilerInstance.h"
-#include "clang/SPIRV/EmitSPIRVOptions.h"
 #include "clang/SPIRV/FeatureManager.h"
 #include "clang/SPIRV/ModuleBuilder.h"
 #include "llvm/ADT/STLExtras.h"
@@ -46,7 +45,7 @@ namespace spirv {
 /// through the AST is done manually instead of using ASTConsumer's harness.
 class SPIRVEmitter : public ASTConsumer {
 public:
-  SPIRVEmitter(CompilerInstance &ci, EmitSPIRVOptions &options);
+  SPIRVEmitter(CompilerInstance &ci);
 
   void HandleTranslationUnit(ASTContext &context) override;
 
@@ -152,7 +151,7 @@ private:
   /// Decomposes and reconstructs the given srcVal of the given valType to meet
   /// the requirements of the dstLR layout rule.
   uint32_t reconstructValue(const SpirvEvalInfo &srcVal, QualType valType,
-                            LayoutRule dstLR);
+                            SpirvLayoutRule dstLR);
 
   /// Generates the necessary instructions for conducting the given binary
   /// operation on lhs and rhs.
@@ -919,7 +918,7 @@ private:
   ASTContext &astContext;
   DiagnosticsEngine &diags;
 
-  const EmitSPIRVOptions &spirvOptions;
+  SpirvCodeGenOptions &spirvOptions;
 
   /// Entry function name and shader stage. Both of them are derived from the
   /// command line and should be const.

+ 8 - 7
tools/clang/lib/SPIRV/SpirvEvalInfo.h

@@ -78,8 +78,8 @@ public:
   inline SpirvEvalInfo &setStorageClass(spv::StorageClass sc);
   spv::StorageClass getStorageClass() const { return storageClass; }
 
-  inline SpirvEvalInfo &setLayoutRule(LayoutRule rule);
-  LayoutRule getLayoutRule() const { return layoutRule; }
+  inline SpirvEvalInfo &setLayoutRule(SpirvLayoutRule rule);
+  SpirvLayoutRule getLayoutRule() const { return layoutRule; }
 
   inline SpirvEvalInfo &setRValue(bool rvalue = true);
   bool isRValue() const { return isRValue_; }
@@ -109,7 +109,7 @@ private:
   bool containsAlias;
 
   spv::StorageClass storageClass;
-  LayoutRule layoutRule;
+  SpirvLayoutRule layoutRule;
 
   bool isRValue_;
   bool isConstant_;
@@ -120,9 +120,10 @@ private:
 
 SpirvEvalInfo::SpirvEvalInfo(uint32_t id)
     : resultId(id), containsAlias(false),
-      storageClass(spv::StorageClass::Function), layoutRule(LayoutRule::Void),
-      isRValue_(false), isConstant_(false), isSpecConstant_(false),
-      isRelaxedPrecision_(false), isNonUniform_(false) {}
+      storageClass(spv::StorageClass::Function),
+      layoutRule(SpirvLayoutRule::Void), isRValue_(false), isConstant_(false),
+      isSpecConstant_(false), isRelaxedPrecision_(false), isNonUniform_(false) {
+}
 
 SpirvEvalInfo &SpirvEvalInfo::setResultId(uint32_t id) {
   resultId = id;
@@ -145,7 +146,7 @@ SpirvEvalInfo &SpirvEvalInfo::setStorageClass(spv::StorageClass sc) {
   return *this;
 }
 
-SpirvEvalInfo &SpirvEvalInfo::setLayoutRule(LayoutRule rule) {
+SpirvEvalInfo &SpirvEvalInfo::setLayoutRule(SpirvLayoutRule rule) {
   layoutRule = rule;
   return *this;
 }

+ 35 - 32
tools/clang/lib/SPIRV/TypeTranslator.cpp

@@ -75,7 +75,7 @@ const hlsl::ConstantPacking *getPackOffset(const NamedDecl *decl) {
 } // anonymous namespace
 
 bool TypeTranslator::isRelaxedPrecisionType(QualType type,
-                                            const EmitSPIRVOptions &opts) {
+                                            const SpirvCodeGenOptions &opts) {
   // Primitive types
   {
     QualType ty = {};
@@ -489,7 +489,7 @@ uint32_t TypeTranslator::getElementSpirvBitwidth(QualType type) {
   llvm_unreachable("invalid type passed to getElementSpirvBitwidth");
 }
 
-uint32_t TypeTranslator::translateType(QualType type, LayoutRule rule) {
+uint32_t TypeTranslator::translateType(QualType type, SpirvLayoutRule rule) {
   const auto desugaredType = desugarType(type);
   if (desugaredType != type) {
     const auto id = translateType(desugaredType, rule);
@@ -510,7 +510,7 @@ uint32_t TypeTranslator::translateType(QualType type, LayoutRule rule) {
           // According to the SPIR-V Spec: There is no physical size or bit
           // pattern defined for boolean type. Therefore an unsigned integer is
           // used to represent booleans when layout is required.
-          if (rule == LayoutRule::Void)
+          if (rule == SpirvLayoutRule::Void)
             return theBuilder.getBoolType();
           else
             return theBuilder.getUint32Type();
@@ -594,7 +594,7 @@ uint32_t TypeTranslator::translateType(QualType type, LayoutRule rule) {
       // If the matrix element type is not float, it is represented as an array
       // of vectors, and should therefore have the ArrayStride decoration.
       llvm::SmallVector<const Decoration *, 4> decorations;
-      if (!elemType->isFloatingType() && rule != LayoutRule::Void) {
+      if (!elemType->isFloatingType() && rule != SpirvLayoutRule::Void) {
         uint32_t stride = 0;
         (void)getAlignmentAndSize(type, rule, &stride);
         decorations.push_back(
@@ -635,7 +635,7 @@ uint32_t TypeTranslator::translateType(QualType type, LayoutRule rule) {
     }
 
     llvm::SmallVector<const Decoration *, 4> decorations;
-    if (rule != LayoutRule::Void) {
+    if (rule != SpirvLayoutRule::Void) {
       decorations = getLayoutDecorations(collectDeclsInDeclContext(decl), rule);
     }
 
@@ -649,7 +649,7 @@ uint32_t TypeTranslator::translateType(QualType type, LayoutRule rule) {
     const uint32_t elemTypeId = translateType(elemType, rule);
 
     llvm::SmallVector<const Decoration *, 4> decorations;
-    if (rule != LayoutRule::Void &&
+    if (rule != SpirvLayoutRule::Void &&
         // We won't have stride information for structured/byte buffers since
         // they contain runtime arrays.
         !isAKindOfStructuredOrByteBuffer(elemType)) {
@@ -1304,7 +1304,7 @@ bool TypeTranslator::shouldSkipInStructLayout(const Decl *decl) {
 }
 
 llvm::SmallVector<const Decoration *, 4> TypeTranslator::getLayoutDecorations(
-    const llvm::SmallVector<const Decl *, 4> &decls, LayoutRule rule) {
+    const llvm::SmallVector<const Decl *, 4> &decls, SpirvLayoutRule rule) {
   const auto spirvContext = theBuilder.getSPIRVContext();
   llvm::SmallVector<const Decoration *, 4> decorations;
   uint32_t offset = 0, index = 0;
@@ -1321,9 +1321,9 @@ llvm::SmallVector<const Decoration *, 4> TypeTranslator::getLayoutDecorations(
     // The next avaiable location after layouting the previos members
     const uint32_t nextLoc = offset;
 
-    if (rule == LayoutRule::RelaxedGLSLStd140 ||
-        rule == LayoutRule::RelaxedGLSLStd430 ||
-        rule == LayoutRule::FxcCTBuffer) {
+    if (rule == SpirvLayoutRule::RelaxedGLSLStd140 ||
+        rule == SpirvLayoutRule::RelaxedGLSLStd430 ||
+        rule == SpirvLayoutRule::FxcCTBuffer) {
       alignUsingHLSLRelaxedLayout(fieldType, memberSize, memberAlignment,
                                   &offset);
     } else {
@@ -1426,7 +1426,8 @@ TypeTranslator::collectDeclsInDeclContext(const DeclContext *declContext) {
   return decls;
 }
 
-uint32_t TypeTranslator::translateResourceType(QualType type, LayoutRule rule) {
+uint32_t TypeTranslator::translateResourceType(QualType type,
+                                               SpirvLayoutRule rule) {
   // Resource types are either represented like C struct or C++ class in the
   // AST. Samplers are represented like C struct, so isStructureType() will
   // return true for it; textures are represented like C++ class, so
@@ -1488,7 +1489,7 @@ uint32_t TypeTranslator::translateResourceType(QualType type, LayoutRule rule) {
     // The aliased-to variable should surely be in the Uniform storage class,
     // which has layout decorations.
     bool asAlias = false;
-    if (rule == LayoutRule::Void) {
+    if (rule == SpirvLayoutRule::Void) {
       asAlias = true;
       rule = spirvOptions.sBufferLayoutRule;
     }
@@ -1539,7 +1540,7 @@ uint32_t TypeTranslator::translateResourceType(QualType type, LayoutRule rule) {
   // ByteAddressBuffer types.
   if (name == "ByteAddressBuffer") {
     const auto bufferType = theBuilder.getByteAddressBufferType(/*isRW*/ false);
-    if (rule == LayoutRule::Void) {
+    if (rule == SpirvLayoutRule::Void) {
       // All byte address buffers are in the Uniform storage class.
       return theBuilder.getPointerType(bufferType, spv::StorageClass::Uniform);
     } else {
@@ -1549,7 +1550,7 @@ uint32_t TypeTranslator::translateResourceType(QualType type, LayoutRule rule) {
   // RWByteAddressBuffer types.
   if (name == "RWByteAddressBuffer") {
     const auto bufferType = theBuilder.getByteAddressBufferType(/*isRW*/ true);
-    if (rule == LayoutRule::Void) {
+    if (rule == SpirvLayoutRule::Void) {
       // All byte address buffers are in the Uniform storage class.
       return theBuilder.getPointerType(bufferType, spv::StorageClass::Uniform);
     } else {
@@ -1707,7 +1708,7 @@ void TypeTranslator::alignUsingHLSLRelaxedLayout(QualType fieldType,
   if (fieldIsVecType) {
     uint32_t scalarAlignment = 0;
     std::tie(scalarAlignment, std::ignore) =
-        getAlignmentAndSize(vecElemType, LayoutRule::Void, nullptr);
+        getAlignmentAndSize(vecElemType, SpirvLayoutRule::Void, nullptr);
     if (scalarAlignment <= 4)
       fieldAlignment = scalarAlignment;
   }
@@ -1724,7 +1725,7 @@ void TypeTranslator::alignUsingHLSLRelaxedLayout(QualType fieldType,
 }
 
 std::pair<uint32_t, uint32_t>
-TypeTranslator::getAlignmentAndSize(QualType type, LayoutRule rule,
+TypeTranslator::getAlignmentAndSize(QualType type, SpirvLayoutRule rule,
                                     uint32_t *stride) {
   // std140 layout rules:
 
@@ -1853,7 +1854,8 @@ TypeTranslator::getAlignmentAndSize(QualType type, LayoutRule rule,
       uint32_t alignment = 0, size = 0;
       std::tie(alignment, size) = getAlignmentAndSize(elemType, rule, stride);
       // Use element alignment for fxc rules
-      if (rule != LayoutRule::FxcCTBuffer && rule != LayoutRule::FxcSBuffer)
+      if (rule != SpirvLayoutRule::FxcCTBuffer &&
+          rule != SpirvLayoutRule::FxcSBuffer)
         alignment = (elemCount == 3 ? 4 : elemCount) * size;
 
       return {alignment, elemCount * size};
@@ -1875,16 +1877,16 @@ TypeTranslator::getAlignmentAndSize(QualType type, LayoutRule rule,
 
       const uint32_t vecStorageSize = isRowMajor ? colCount : rowCount;
 
-      if (rule == LayoutRule::FxcSBuffer) {
+      if (rule == SpirvLayoutRule::FxcSBuffer) {
         *stride = vecStorageSize * size;
         // Use element alignment for fxc structured buffers
         return {alignment, rowCount * colCount * size};
       }
 
       alignment *= (vecStorageSize == 3 ? 4 : vecStorageSize);
-      if (rule == LayoutRule::GLSLStd140 ||
-          rule == LayoutRule::RelaxedGLSLStd140 ||
-          rule == LayoutRule::FxcCTBuffer) {
+      if (rule == SpirvLayoutRule::GLSLStd140 ||
+          rule == SpirvLayoutRule::RelaxedGLSLStd140 ||
+          rule == SpirvLayoutRule::FxcCTBuffer) {
         alignment = roundToPow2(alignment, kStd140Vec4Alignment);
       }
       *stride = alignment;
@@ -1909,9 +1911,9 @@ TypeTranslator::getAlignmentAndSize(QualType type, LayoutRule rule,
       std::tie(memberAlignment, memberSize) =
           getAlignmentAndSize(field->getType(), rule, stride);
 
-      if (rule == LayoutRule::RelaxedGLSLStd140 ||
-          rule == LayoutRule::RelaxedGLSLStd430 ||
-          rule == LayoutRule::FxcCTBuffer) {
+      if (rule == SpirvLayoutRule::RelaxedGLSLStd140 ||
+          rule == SpirvLayoutRule::RelaxedGLSLStd430 ||
+          rule == SpirvLayoutRule::FxcCTBuffer) {
         alignUsingHLSLRelaxedLayout(field->getType(), memberSize,
                                     memberAlignment, &structSize);
       } else {
@@ -1932,13 +1934,14 @@ TypeTranslator::getAlignmentAndSize(QualType type, LayoutRule rule,
       structSize += memberSize;
     }
 
-    if (rule == LayoutRule::GLSLStd140 ||
-        rule == LayoutRule::RelaxedGLSLStd140) {
+    if (rule == SpirvLayoutRule::GLSLStd140 ||
+        rule == SpirvLayoutRule::RelaxedGLSLStd140) {
       // ... and rounded up to the base alignment of a vec4.
       maxAlignment = roundToPow2(maxAlignment, kStd140Vec4Alignment);
     }
 
-    if (rule != LayoutRule::FxcCTBuffer && rule != LayoutRule::FxcSBuffer) {
+    if (rule != SpirvLayoutRule::FxcCTBuffer &&
+        rule != SpirvLayoutRule::FxcSBuffer) {
       // The base offset of the member following the sub-structure is rounded up
       // to the next multiple of the base alignment of the structure.
       structSize = roundToPow2(structSize, maxAlignment);
@@ -1953,21 +1956,21 @@ TypeTranslator::getAlignmentAndSize(QualType type, LayoutRule rule,
     std::tie(alignment, size) =
         getAlignmentAndSize(arrayType->getElementType(), rule, stride);
 
-    if (rule == LayoutRule::FxcSBuffer) {
+    if (rule == SpirvLayoutRule::FxcSBuffer) {
       *stride = size;
       // Use element alignment for fxc structured buffers
       return {alignment, size * elemCount};
     }
 
-    if (rule == LayoutRule::GLSLStd140 ||
-        rule == LayoutRule::RelaxedGLSLStd140 ||
-        rule == LayoutRule::FxcCTBuffer) {
+    if (rule == SpirvLayoutRule::GLSLStd140 ||
+        rule == SpirvLayoutRule::RelaxedGLSLStd140 ||
+        rule == SpirvLayoutRule::FxcCTBuffer) {
       // The base alignment and array stride are set to match the base alignment
       // of a single array element, according to rules 1, 2, and 3, and rounded
       // up to the base alignment of a vec4.
       alignment = roundToPow2(alignment, kStd140Vec4Alignment);
     }
-    if (rule == LayoutRule::FxcCTBuffer) {
+    if (rule == SpirvLayoutRule::FxcCTBuffer) {
       // In fxc cbuffer/tbuffer packing rules, arrays does not affect the data
       // packing after it. But we still need to make sure paddings are inserted
       // internally if necessary.

+ 8 - 8
tools/clang/lib/SPIRV/TypeTranslator.h

@@ -14,8 +14,8 @@
 
 #include "clang/AST/Type.h"
 #include "clang/Basic/Diagnostic.h"
-#include "clang/SPIRV/EmitSPIRVOptions.h"
 #include "clang/SPIRV/ModuleBuilder.h"
+#include "dxc/Support/SPIRVOptions.h"
 #include "llvm/ADT/Optional.h"
 
 #include "SpirvEvalInfo.h"
@@ -33,7 +33,7 @@ namespace spirv {
 class TypeTranslator {
 public:
   TypeTranslator(ASTContext &context, ModuleBuilder &builder,
-                 DiagnosticsEngine &diag, const EmitSPIRVOptions &opts)
+                 DiagnosticsEngine &diag, const SpirvCodeGenOptions &opts)
       : astContext(context), theBuilder(builder), diags(diag),
         spirvOptions(opts) {}
 
@@ -53,7 +53,7 @@ public:
   /// on will be generated and all with layout decorations (if decorateLayout
   /// is true).
   uint32_t translateType(QualType type,
-                         LayoutRule layoutRule = LayoutRule::Void);
+                         SpirvLayoutRule layoutRule = SpirvLayoutRule::Void);
 
   /// \brief Generates the SPIR-V type for the counter associated with a
   /// {Append|Consume}StructuredBuffer: an OpTypeStruct with a single 32-bit
@@ -201,7 +201,7 @@ public:
   /// \brief Returns true if the given type can use relaxed precision
   /// decoration. Integer and float types with lower than 32 bits can be
   /// operated on with a relaxed precision.
-  static bool isRelaxedPrecisionType(QualType, const EmitSPIRVOptions &);
+  static bool isRelaxedPrecisionType(QualType, const SpirvCodeGenOptions &);
 
   /// Returns true if the given type will be translated into a SPIR-V image,
   /// sampler or struct containing images or samplers.
@@ -257,7 +257,7 @@ public:
   /// of a struct member.
   llvm::SmallVector<const Decoration *, 4>
   getLayoutDecorations(const llvm::SmallVector<const Decl *, 4> &declGroup,
-                       LayoutRule rule);
+                       SpirvLayoutRule rule);
 
   /// \brief Returns how many sequential locations are consumed by a given type.
   uint32_t getLocationCount(QualType type);
@@ -297,7 +297,7 @@ private:
 
   /// \brief Translates the given HLSL resource type into its SPIR-V
   /// instructions and returns the <result-id>. Returns 0 on failure.
-  uint32_t translateResourceType(QualType type, LayoutRule rule);
+  uint32_t translateResourceType(QualType type, SpirvLayoutRule rule);
 
   /// \brief For the given sampled type, returns the corresponding image format
   /// that can be used to create an image object.
@@ -324,7 +324,7 @@ public:
   /// to get the next available location (alignment + size), which means
   /// size contains post-paddings required by the given type.
   std::pair<uint32_t, uint32_t>
-  getAlignmentAndSize(QualType type, LayoutRule rule, uint32_t *stride);
+  getAlignmentAndSize(QualType type, SpirvLayoutRule rule, uint32_t *stride);
 
   /// \brief If a hint exists regarding the usage of literal types, it
   /// is returned. Otherwise, the given type itself is returned.
@@ -368,7 +368,7 @@ private:
   ASTContext &astContext;
   ModuleBuilder &theBuilder;
   DiagnosticsEngine &diags;
-  const EmitSPIRVOptions &spirvOptions;
+  const SpirvCodeGenOptions &spirvOptions;
 
   /// \brief This is a stack which is used to track the intended usage type for
   /// literals. For example: while a floating literal is being visited, if the

+ 19 - 37
tools/clang/tools/dxcompiler/dxcompilerobj.cpp

@@ -509,43 +509,25 @@ public:
       // SPIRV change starts
 #ifdef ENABLE_SPIRV_CODEGEN
       else if (opts.GenSPIRV) {
-          clang::EmitSPIRVOptions spirvOpts;
-
-          spirvOpts.codeGenHighLevel = opts.CodeGenHighLevel;
-          spirvOpts.disableValidation = opts.DisableValidation;
-          spirvOpts.invertY = opts.VkInvertY;
-          spirvOpts.invertW = opts.VkInvertW;
-          spirvOpts.useGlLayout = opts.VkUseGlLayout;
-          spirvOpts.useDxLayout = opts.VkUseDxLayout;
-          spirvOpts.enableReflect = opts.SpvEnableReflect;
-          spirvOpts.defaultRowMajor = opts.DefaultRowMajor;
-          spirvOpts.stageIoOrder = opts.VkStageIoOrder;
-          spirvOpts.noWarnIgnoredFeatures = opts.VkNoWarnIgnoredFeatures;
-          spirvOpts.bShift = opts.VkBShift;
-          spirvOpts.tShift = opts.VkTShift;
-          spirvOpts.sShift = opts.VkSShift;
-          spirvOpts.uShift = opts.VkUShift;
-          spirvOpts.bindRegister = opts.VkBindRegister;
-          spirvOpts.allowedExtensions = opts.SpvExtensions;
-          spirvOpts.targetEnv = opts.SpvTargetEnv;
-          spirvOpts.enable16BitTypes = opts.Enable16BitTypes;
-          spirvOpts.debugInfoFile = opts.SpvDebugFile;
-          spirvOpts.debugInfoSource = opts.SpvDebugSource;
-          spirvOpts.debugInfoLine = opts.SpvDebugLine;
-          spirvOpts.debugInfoTool = opts.SpvDebugTool;
-          spirvOpts.optConfig = opts.SpvOconfig;
-
-          // Store a string representation of command line options.
-          if (opts.DebugInfo)
-            for (auto opt : mainArgs.getArrayRef())
-              spirvOpts.clOptions += " " + std::string(opt);
-
-          clang::EmitSPIRVAction action(spirvOpts);
-          FrontendInputFile file(utf8SourceName.m_psz, IK_HLSL);
-          action.BeginSourceFile(compiler, file);
-          action.Execute();
-          action.EndSourceFile();
-          outStream.flush();
+        // Since SpirvOptions is passed to the SPIR-V CodeGen as a whole
+        // structure, we need to copy a few non-spirv-specific options into the
+        // structure.
+        opts.SpirvOptions.enable16BitTypes = opts.Enable16BitTypes;
+        opts.SpirvOptions.codeGenHighLevel = opts.CodeGenHighLevel;
+        opts.SpirvOptions.defaultRowMajor = opts.DefaultRowMajor;
+        opts.SpirvOptions.disableValidation = opts.DisableValidation;
+        // Store a string representation of command line options.
+        if (opts.DebugInfo)
+          for (auto opt : mainArgs.getArrayRef())
+            opts.SpirvOptions.clOptions += " " + std::string(opt);
+
+        compiler.getCodeGenOpts().SpirvOptions = opts.SpirvOptions;
+        clang::EmitSPIRVAction action;
+        FrontendInputFile file(utf8SourceName.m_psz, IK_HLSL);
+        action.BeginSourceFile(compiler, file);
+        action.Execute();
+        action.EndSourceFile();
+        outStream.flush();
       }
 #endif
       // SPIRV change ends