summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libGLESv2/D3DConstantTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/D3DConstantTable.cpp')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/D3DConstantTable.cpp231
1 files changed, 231 insertions, 0 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/D3DConstantTable.cpp b/src/3rdparty/angle/src/libGLESv2/D3DConstantTable.cpp
new file mode 100644
index 0000000000..e136951bec
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/D3DConstantTable.cpp
@@ -0,0 +1,231 @@
+//
+// Copyright (c) 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.
+//
+
+// D3DConstantTable.cpp: Implements the D3DConstantTable class which parses
+// information about constants from the CTAB comment in a D3D shader blob.
+// Restructures the constant table as a hierarchy of constants in the same
+// way as D3DX.
+
+#include "libGLESv2/D3DConstantTable.h"
+
+#include <d3d9.h>
+#include <d3d9types.h>
+#include <windows.h>
+#include <mmsystem.h>
+
+#include "libGLESv2/BinaryStream.h"
+
+const static int SHADER_VERSION_MASK = D3DVS_VERSION(0, 0);
+const static int FOURCC_CTAB = MAKEFOURCC('C','T','A','B');
+
+namespace gl
+{
+// These structs and constants correspond to the format of the constant table in a shader binary.
+// They match the corresponding structures in d3dx9shader.h.
+namespace ctab
+{
+struct ConstantTable
+{
+ DWORD size;
+ DWORD creator;
+ DWORD version;
+ DWORD constants;
+ DWORD constantInfos;
+ DWORD flags;
+ DWORD target;
+};
+
+struct ConstantInfo
+{
+ DWORD name;
+ WORD registerSet;
+ WORD registerIndex;
+ WORD registerCount;
+ WORD reserved;
+ DWORD typeInfo;
+ DWORD defaultValue;
+};
+
+struct TypeInfo
+{
+ WORD typeClass;
+ WORD type;
+ WORD rows;
+ WORD columns;
+ WORD elements;
+ WORD structMembers;
+ DWORD structMemberInfos;
+};
+
+struct StructMemberInfo
+{
+ DWORD name;
+ DWORD typeInfo;
+};
+}
+
+D3DConstant::D3DConstant(const char *base, const ctab::ConstantInfo *constantInfo)
+{
+ const ctab::TypeInfo *typeInfo = reinterpret_cast<const ctab::TypeInfo*>(base + constantInfo->typeInfo);
+
+ name = base + constantInfo->name;
+ registerSet = static_cast<RegisterSet>(constantInfo->registerSet);
+ registerIndex = constantInfo->registerIndex;
+ registerCount = constantInfo->registerCount;
+ typeClass = static_cast<Class>(typeInfo->typeClass);
+ type = static_cast<Type>(typeInfo->type);
+ rows = typeInfo->rows;
+ columns = typeInfo->columns;
+ elements = typeInfo->elements;
+
+ if (typeClass == CLASS_STRUCT)
+ {
+ addStructMembers(base, registerSet, registerIndex, typeInfo);
+ }
+}
+
+D3DConstant::D3DConstant(const char *base, RegisterSet registerSet, unsigned registerIndex, const ctab::StructMemberInfo *memberInfo)
+ : registerSet(registerSet), registerIndex(registerIndex)
+{
+ const ctab::TypeInfo *typeInfo = reinterpret_cast<const ctab::TypeInfo*>(base + memberInfo->typeInfo);
+
+ name = base + memberInfo->name;
+ registerCount = typeInfo->rows * typeInfo->elements;
+ typeClass = static_cast<Class>(typeInfo->typeClass);
+ type = static_cast<Type>(typeInfo->type);
+ rows = typeInfo->rows;
+ columns = typeInfo->columns;
+ elements = typeInfo->elements;
+
+ if (typeClass == CLASS_STRUCT)
+ {
+ registerCount = addStructMembers(base, registerSet, registerIndex, typeInfo);
+ }
+}
+
+D3DConstant::~D3DConstant()
+{
+ for (size_t j = 0; j < structMembers.size(); ++j)
+ {
+ for (size_t i = 0; i < structMembers[j].size(); ++i)
+ {
+ delete structMembers[j][i];
+ }
+ }
+}
+
+unsigned D3DConstant::addStructMembers(const char *base, RegisterSet registerSet, unsigned registerIndex, const ctab::TypeInfo *typeInfo)
+{
+ const ctab::StructMemberInfo *memberInfos = reinterpret_cast<const ctab::StructMemberInfo*>(
+ base + typeInfo->structMemberInfos);
+
+ unsigned memberIndex = registerIndex;
+
+ structMembers.resize(elements);
+
+ for (unsigned j = 0; j < elements; ++j)
+ {
+ structMembers[j].resize(typeInfo->structMembers);
+
+ for (unsigned i = 0; i < typeInfo->structMembers; ++i)
+ {
+ const ctab::TypeInfo *memberTypeInfo = reinterpret_cast<const ctab::TypeInfo*>(
+ base + memberInfos[i].typeInfo);
+
+ D3DConstant *member = new D3DConstant(base, registerSet, memberIndex, memberInfos + i);
+ memberIndex += member->registerCount;
+
+ structMembers[j][i] = member;
+ }
+ }
+
+ return memberIndex - registerIndex;
+}
+
+D3DConstantTable::D3DConstantTable(void *blob, size_t size) : mError(false)
+{
+ BinaryInputStream stream(blob, size);
+
+ int version;
+ stream.read(&version);
+ if ((version & SHADER_VERSION_MASK) != SHADER_VERSION_MASK)
+ {
+ mError = true;
+ return;
+ }
+
+ const ctab::ConstantTable* constantTable = NULL;
+
+ while (!stream.error())
+ {
+ int token;
+ stream.read(&token);
+
+ if ((token & D3DSI_OPCODE_MASK) == D3DSIO_COMMENT)
+ {
+ size_t length = ((token & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT) * sizeof(DWORD);
+
+ int fourcc;
+ stream.read(&fourcc);
+ if (fourcc == FOURCC_CTAB)
+ {
+ constantTable = reinterpret_cast<const ctab::ConstantTable*>(static_cast<const char*>(blob) + stream.offset());
+ break;
+ }
+
+ stream.skip(length - sizeof(fourcc));
+ }
+ else if (token == D3DSIO_END)
+ {
+ break;
+ }
+ }
+
+ mError = !constantTable || stream.error();
+ if (mError)
+ {
+ return;
+ }
+
+ const char *base = reinterpret_cast<const char*>(constantTable);
+
+ mConstants.resize(constantTable->constants);
+ const ctab::ConstantInfo *constantInfos =
+ reinterpret_cast<const ctab::ConstantInfo*>(base + constantTable->constantInfos);
+ for (size_t i = 0; i < constantTable->constants; ++i)
+ {
+ mConstants[i] = new D3DConstant(base, constantInfos + i);
+ }
+}
+
+D3DConstantTable::~D3DConstantTable()
+{
+ for (size_t i = 0; i < mConstants.size(); ++i)
+ {
+ delete mConstants[i];
+ }
+}
+
+const D3DConstant *D3DConstantTable::getConstant(unsigned index) const
+{
+ return mConstants[index];
+}
+
+const D3DConstant *D3DConstantTable::getConstantByName(const char *name) const
+{
+ for (size_t i = 0; i < mConstants.size(); ++i)
+ {
+ const D3DConstant *constant = getConstant(i);
+ if (constant->name == name)
+ {
+ return constant;
+ }
+ }
+
+ return NULL;
+}
+
+}