Interface design for user-defined name hashing.
1) We use BuiltInResources to pass the hash function to
ANGLE, deciding whether we applies hash function or not.
2) We use 64 bits hashing function, because 64 bits is 16
bytes using hex representation, plus the "webgl_" prefix,
we can keep the names under 128 (WebGL allows 5 levels of
nesting in structures). If chooseing 128 bits, we will
go beyond 128 characters, and some drivers can't handle
that safely.
ANGLEBUG=315
Review URL: https://codereview.appspot.com/6822077
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1466 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/include/GLSLANG/ShaderLang.h b/include/GLSLANG/ShaderLang.h
index d925029..a8dd3b9 100644
--- a/include/GLSLANG/ShaderLang.h
+++ b/include/GLSLANG/ShaderLang.h
@@ -23,6 +23,8 @@
#define COMPILER_EXPORT
#endif
+#include "KHR/khrplatform.h"
+
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler.
@@ -110,7 +112,10 @@
SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
SH_ACTIVE_ATTRIBUTES = 0x8B89,
SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
- SH_MAPPED_NAME_MAX_LENGTH = 0x8B8B
+ SH_MAPPED_NAME_MAX_LENGTH = 0x6000,
+ SH_NAME_MAX_LENGTH = 0x6001,
+ SH_HASHED_NAME_MAX_LENGTH = 0x6002,
+ SH_HASHED_NAMES_COUNT = 0x6003
} ShShaderInfo;
// Compile options.
@@ -145,7 +150,7 @@
SH_DEPENDENCY_GRAPH = 0x0400,
// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
- SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800,
+ SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800
} ShCompileOptions;
//
@@ -160,6 +165,10 @@
//
COMPILER_EXPORT int ShFinalize();
+// The 64 bits hash function. The first parameter is the input string; the
+// second parameter is the string length.
+typedef khronos_uint64_t (*ShHashFunction64)(const char*, size_t);
+
//
// Implementation dependent built-in resources (constants and extensions).
// The names for these resources has been obtained by stripping gl_/GL_.
@@ -181,6 +190,11 @@
int OES_standard_derivatives;
int OES_EGL_image_external;
int ARB_texture_rectangle;
+
+ // Name Hashing.
+ // Set a 64 bit hash function to enable user-defined name hashing.
+ // Default is NULL.
+ ShHashFunction64 HashFunction;
} ShBuiltInResources;
//
@@ -267,6 +281,11 @@
// termination character.
// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including
// the null termination character.
+// SH_NAME_MAX_LENGTH: the max length of a user-defined name including the
+// null termination character.
+// SH_HASHED_NAME_MAX_LENGTH: the max length of a hashed name including the
+// null termination character.
+// SH_HASHED_NAMES_COUNT: the number of hashed names from the latest compile.
//
// params: Requested parameter
COMPILER_EXPORT void ShGetInfo(const ShHandle handle,
@@ -347,6 +366,24 @@
char* name,
char* mappedName);
+// Returns information about a name hashing entry from the latest compile.
+// Parameters:
+// handle: Specifies the compiler
+// index: Specifies the index of the name hashing entry to be queried.
+// name: Returns a null terminated string containing the user defined name.
+// It is assumed that name has enough memory to accomodate the name.
+// The size of the buffer required to store the user defined name can
+// be obtained by calling ShGetInfo with SH_NAME_MAX_LENGTH.
+// hashedName: Returns a null terminated string containing the hashed name of
+// the uniform variable, It is assumed that hashedName has enough
+// memory to accomodate the name. The size of the buffer required
+// to store the name can be obtained by calling ShGetInfo with
+// SH_HASHED_NAME_MAX_LENGTH.
+COMPILER_EXPORT void ShGetNameHashingEntry(const ShHandle handle,
+ int index,
+ char* name,
+ char* hashedName);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/build_angle.gypi b/src/build_angle.gypi
index 5ca5c08..e72aec6 100644
--- a/src/build_angle.gypi
+++ b/src/build_angle.gypi
@@ -79,6 +79,7 @@
'compiler/glslang_lex.cpp',
'compiler/glslang_tab.cpp',
'compiler/glslang_tab.h',
+ 'compiler/HashNames.h',
'compiler/InfoSink.cpp',
'compiler/InfoSink.h',
'compiler/Initialize.cpp',
diff --git a/src/common/version.h b/src/common/version.h
index cd16882..536f6fb 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -1,7 +1,7 @@
#define MAJOR_VERSION 1
#define MINOR_VERSION 1
#define BUILD_VERSION 0
-#define BUILD_REVISION 1382
+#define BUILD_REVISION 1384
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp
index 9e7f75c..b067fed 100644
--- a/src/compiler/Compiler.cpp
+++ b/src/compiler/Compiler.cpp
@@ -124,6 +124,8 @@
return false;
InitExtensionBehavior(resources, extensionBehavior);
+ hashFunction = resources.HashFunction;
+
return true;
}
diff --git a/src/compiler/HashNames.h b/src/compiler/HashNames.h
new file mode 100644
index 0000000..d2141e2
--- /dev/null
+++ b/src/compiler/HashNames.h
@@ -0,0 +1,19 @@
+//
+// Copyright (c) 2002-2012 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.
+//
+
+#ifndef COMPILER_HASH_NAMES_H_
+#define COMPILER_HASH_NAMES_H_
+
+#include <map>
+
+#include "compiler/intermediate.h"
+#include "GLSLANG/ShaderLang.h"
+
+#define HASHED_NAME_PREFIX "webgl_"
+
+typedef std::map<TPersistString, TPersistString> NameMap;
+
+#endif // COMPILER_HASH_NAMES_H_
diff --git a/src/compiler/ShHandle.h b/src/compiler/ShHandle.h
index 6ba302a..0c77bb0 100644
--- a/src/compiler/ShHandle.h
+++ b/src/compiler/ShHandle.h
@@ -18,6 +18,7 @@
#include "compiler/BuiltInFunctionEmulator.h"
#include "compiler/ExtensionBehavior.h"
+#include "compiler/HashNames.h"
#include "compiler/InfoSink.h"
#include "compiler/SymbolTable.h"
#include "compiler/VariableInfo.h"
@@ -68,6 +69,9 @@
const TVariableInfoList& getUniforms() const { return uniforms; }
int getMappedNameMaxLength() const;
+ ShHashFunction64 getHashFunction() const { return hashFunction; }
+ const NameMap& getNameMap() const { return nameMap; }
+
protected:
ShShaderType getShaderType() const { return shaderType; }
ShShaderSpec getShaderSpec() const { return shaderSpec; }
@@ -124,6 +128,10 @@
// Cached copy of the ref-counted singleton.
LongNameMap* longNameMap;
+
+ // name hashing.
+ ShHashFunction64 hashFunction;
+ NameMap nameMap;
};
//
diff --git a/src/compiler/ShaderLang.cpp b/src/compiler/ShaderLang.cpp
index 56f5c7f..ab56538 100644
--- a/src/compiler/ShaderLang.cpp
+++ b/src/compiler/ShaderLang.cpp
@@ -125,6 +125,9 @@
resources->OES_standard_derivatives = 0;
resources->OES_EGL_image_external = 0;
resources->ARB_texture_rectangle = 0;
+
+ // Disable name hashing by default.
+ resources->HashFunction = NULL;
}
//
@@ -224,6 +227,22 @@
// handle array and struct dereferences.
*params = 1 + MAX_SYMBOL_NAME_LEN;
break;
+ case SH_NAME_MAX_LENGTH:
+ *params = 1 + MAX_SYMBOL_NAME_LEN;
+ break;
+ case SH_HASHED_NAME_MAX_LENGTH:
+ if (compiler->getHashFunction() == NULL) {
+ *params = 0;
+ } else {
+ // 64 bits hashing output requires 16 bytes for hex
+ // representation.
+ const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
+ *params = 16 + sizeof(HashedNamePrefix);
+ }
+ break;
+ case SH_HASHED_NAMES_COUNT:
+ *params = compiler->getNameMap().size();
+ break;
default: UNREACHABLE();
}
}
@@ -283,3 +302,46 @@
getVariableInfo(SH_ACTIVE_UNIFORMS,
handle, index, length, size, type, name, mappedName);
}
+
+void ShGetNameHashingEntry(const ShHandle handle,
+ int index,
+ char* name,
+ char* hashedName)
+{
+ if (!handle || !name || !hashedName || index < 0)
+ return;
+
+ TShHandleBase* base = static_cast<TShHandleBase*>(handle);
+ TCompiler* compiler = base->getAsCompiler();
+ if (!compiler) return;
+
+ const NameMap& nameMap = compiler->getNameMap();
+ if (index >= static_cast<int>(nameMap.size()))
+ return;
+
+ NameMap::const_iterator it = nameMap.begin();
+ for (int i = 0; i < index; ++i)
+ ++it;
+
+ size_t len = it->first.length() + 1;
+ int max_len = 0;
+ ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
+ if (static_cast<int>(len) > max_len) {
+ ASSERT(false);
+ len = max_len;
+ }
+ strncpy(name, it->first.c_str(), len);
+ // To be on the safe side in case the source is longer than expected.
+ name[len] = '\0';
+
+ len = it->second.length() + 1;
+ max_len = 0;
+ ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
+ if (static_cast<int>(len) > max_len) {
+ ASSERT(false);
+ len = max_len;
+ }
+ strncpy(hashedName, it->second.c_str(), len);
+ // To be on the safe side in case the source is longer than expected.
+ hashedName[len] = '\0';
+}
diff --git a/src/compiler/translator_common.vcxproj b/src/compiler/translator_common.vcxproj
index 6d8d530..0f383db 100644
--- a/src/compiler/translator_common.vcxproj
+++ b/src/compiler/translator_common.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -234,6 +234,7 @@
<ClInclude Include="Diagnostics.h" />
<ClInclude Include="DirectiveHandler.h" />
<ClInclude Include="ForLoopUnroll.h" />
+ <ClInclude Include="HashNames.h" />
<ClInclude Include="InfoSink.h" />
<ClInclude Include="Initialize.h" />
<ClInclude Include="InitializeDll.h" />
diff --git a/src/compiler/translator_common.vcxproj.filters b/src/compiler/translator_common.vcxproj.filters
index b460cfa..2de9243 100644
--- a/src/compiler/translator_common.vcxproj.filters
+++ b/src/compiler/translator_common.vcxproj.filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
@@ -253,6 +253,9 @@
<ClInclude Include="depgraph\DependencyGraphOutput.h">
<Filter>Header Files\depgraph</Filter>
</ClInclude>
+ <ClInclude Include="HashNames.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="glslang.l">