diff options
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/D3DConstantTable.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libGLESv2/D3DConstantTable.cpp | 231 |
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; +} + +} |