ES31: Support shader storage buffer in D3D-API side.

Bug: angleproject:1951
Test: angle_end2end_tests

Change-Id: I0d8a4f8cf00fc7fd2d85315138e2b7457fd0b90c
Reviewed-on: https://chromium-review.googlesource.com/1242846
Commit-Queue: Jiajia Qin <jiajia.qin@intel.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 65925f7..457f412 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -314,6 +314,11 @@
     builtInFunctionEmulator.cleanup();
 }
 
+const std::map<std::string, unsigned int> &OutputHLSL::getShaderStorageBlockRegisterMap() const
+{
+    return mResourcesHLSL->getShaderStorageBlockRegisterMap();
+}
+
 const std::map<std::string, unsigned int> &OutputHLSL::getUniformBlockRegisterMap() const
 {
     return mResourcesHLSL->getUniformBlockRegisterMap();
diff --git a/src/compiler/translator/OutputHLSL.h b/src/compiler/translator/OutputHLSL.h
index 7a2690d..b861cca 100644
--- a/src/compiler/translator/OutputHLSL.h
+++ b/src/compiler/translator/OutputHLSL.h
@@ -52,6 +52,7 @@
 
     void output(TIntermNode *treeRoot, TInfoSinkBase &objSink);
 
+    const std::map<std::string, unsigned int> &getShaderStorageBlockRegisterMap() const;
     const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const;
     const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
 
diff --git a/src/compiler/translator/ResourcesHLSL.h b/src/compiler/translator/ResourcesHLSL.h
index 1cd344e..5dd02b2 100644
--- a/src/compiler/translator/ResourcesHLSL.h
+++ b/src/compiler/translator/ResourcesHLSL.h
@@ -44,6 +44,11 @@
     static TString InterfaceBlockInstanceString(const ImmutableString &instanceName,
                                                 unsigned int arrayIndex);
 
+    const std::map<std::string, unsigned int> &getShaderStorageBlockRegisterMap() const
+    {
+        return mShaderStorageBlockRegisterMap;
+    }
+
     const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const
     {
         return mUniformBlockRegisterMap;
diff --git a/src/compiler/translator/ShaderLang.cpp b/src/compiler/translator/ShaderLang.cpp
index 21e3e72..f8f59e1 100644
--- a/src/compiler/translator/ShaderLang.cpp
+++ b/src/compiler/translator/ShaderLang.cpp
@@ -496,6 +496,28 @@
     return CheckVariablesInPackingLimits(maxVectors, variables);
 }
 
+bool GetShaderStorageBlockRegister(const ShHandle handle,
+                                   const std::string &shaderStorageBlockName,
+                                   unsigned int *indexOut)
+{
+#ifdef ANGLE_ENABLE_HLSL
+    ASSERT(indexOut);
+
+    TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+    ASSERT(translator);
+
+    if (!translator->hasShaderStorageBlock(shaderStorageBlockName))
+    {
+        return false;
+    }
+
+    *indexOut = translator->getShaderStorageBlockRegister(shaderStorageBlockName);
+    return true;
+#else
+    return false;
+#endif  // ANGLE_ENABLE_HLSL
+}
+
 bool GetUniformBlockRegister(const ShHandle handle,
                              const std::string &uniformBlockName,
                              unsigned int *indexOut)
diff --git a/src/compiler/translator/TranslatorHLSL.cpp b/src/compiler/translator/TranslatorHLSL.cpp
index 26623a2..433f977 100644
--- a/src/compiler/translator/TranslatorHLSL.cpp
+++ b/src/compiler/translator/TranslatorHLSL.cpp
@@ -139,6 +139,7 @@
 
     outputHLSL.output(root, getInfoSink().obj);
 
+    mShaderStorageBlockRegisterMap = outputHLSL.getShaderStorageBlockRegisterMap();
     mUniformBlockRegisterMap   = outputHLSL.getUniformBlockRegisterMap();
     mUniformRegisterMap        = outputHLSL.getUniformRegisterMap();
 }
@@ -149,6 +150,18 @@
     return false;
 }
 
+bool TranslatorHLSL::hasShaderStorageBlock(const std::string &uniformBlockName) const
+{
+    return (mShaderStorageBlockRegisterMap.count(uniformBlockName) > 0);
+}
+
+unsigned int TranslatorHLSL::getShaderStorageBlockRegister(
+    const std::string &shaderStorageBlockName) const
+{
+    ASSERT(hasShaderStorageBlock(shaderStorageBlockName));
+    return mShaderStorageBlockRegisterMap.find(shaderStorageBlockName)->second;
+}
+
 bool TranslatorHLSL::hasUniformBlock(const std::string &uniformBlockName) const
 {
     return (mUniformBlockRegisterMap.count(uniformBlockName) > 0);
diff --git a/src/compiler/translator/TranslatorHLSL.h b/src/compiler/translator/TranslatorHLSL.h
index d7005a6..31bc2e2 100644
--- a/src/compiler/translator/TranslatorHLSL.h
+++ b/src/compiler/translator/TranslatorHLSL.h
@@ -18,6 +18,9 @@
     TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
     TranslatorHLSL *getAsTranslatorHLSL() override { return this; }
 
+    bool hasShaderStorageBlock(const std::string &interfaceBlockName) const;
+    unsigned int getShaderStorageBlockRegister(const std::string &interfaceBlockName) const;
+
     bool hasUniformBlock(const std::string &interfaceBlockName) const;
     unsigned int getUniformBlockRegister(const std::string &interfaceBlockName) const;
 
@@ -32,6 +35,7 @@
     // collectVariables needs to be run always so registers can be assigned.
     bool shouldCollectVariables(ShCompileOptions compileOptions) override { return true; }
 
+    std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap;
     std::map<std::string, unsigned int> mUniformBlockRegisterMap;
     std::map<std::string, unsigned int> mUniformRegisterMap;
 };