void tVertexDescription::AddVertexBufferAttribute(eVertexBufferAttributeType elementType, eVertexBufferAttributeDataType dataType, unsigned long offsetInBytes, unsigned long strideInBytes) { m_VertexAttributeList.push_back(tVertexBufferAttribute(elementType, dataType, GetVertexBufferAttributeCount(elementType), GetDataTypeSize(dataType), offsetInBytes, strideInBytes)); }
void* x86MsStdcall::GetArgumentPtr(int iIndex, CRegisters* pRegisters) { int iOffset = 4; for(int i=0; i < iIndex; i++) { iOffset += GetDataTypeSize(m_vecArgTypes[i], m_iAlignment); } return (void *) (pRegisters->m_esp->GetValue<unsigned long>() + iOffset); }
bool RPCFile::Open(FileReader* file) { Close(); m_file = file; m_file->SetReadPtr(0); int32_t signature; bool headerOK = m_file->ReadInt32(&signature) && m_file->ReadUInt32(&m_fileVersion) && m_file->ReadUInt32(&m_numParticles) && m_file->ReadUInt32(&m_numChannels) && m_file->ReadFloatBuffer(m_bboxMin, 3) && m_file->ReadFloatBuffer(m_bboxMax, 3); if( !headerOK || (signature != RPC_SIGNATURE) || (m_fileVersion < RPC_MIN_SUPPORTED_VERSION) || (m_fileVersion > RPC_MAX_SUPPORTED_VERSION) ) return false; m_channels = new(std::nothrow) ChannelInfo[m_numChannels]; if(!m_channels) return false; for(uint32_t chanIdx = 0; chanIdx < m_numChannels; ++chanIdx) { ChannelInfo* channel = &m_channels[chanIdx]; uint32_t nameLen; if(!m_file->ReadUInt32(&nameLen) || (nameLen < 2)) return false; channel->m_name = (char*)malloc(nameLen); if(!channel->m_name || !m_file->ReadData(channel->m_name, nameLen)) return false; channel->m_name[nameLen - 1] = 0; uint32_t dataType; if(!m_file->ReadUInt32(&dataType) || (dataType < 1) || (dataType >= ChannelDataType_NUM) || !m_file->ReadUInt64(&channel->m_dataOffset) || !m_file->ReadUInt64(&channel->m_compressedSize)) return false; channel->m_dataType = (ChannelDataType)dataType; uint32_t elemSize = GetDataTypeSize(channel->m_dataType); uint32_t compSize = elemSize / GetDataTypeNumComponents(channel->m_dataType); uint32_t limitsSize = 3*elemSize + 2*compSize; channel->m_valueLimits = malloc(limitsSize); if(!channel->m_valueLimits || !m_file->ReadData(channel->m_valueLimits, limitsSize)) return false; channel->m_decompressedSize = m_numParticles * elemSize; } return true; }
int x86MsStdcall::GetPopSize() { int iPopSize = 0; for(unsigned int i=0; i < m_vecArgTypes.size(); i++) { iPopSize += GetDataTypeSize(m_vecArgTypes[i], m_iAlignment); } return iPopSize; }
int tVertexDescription::AddVertexAttribute(const tVertexAttribute& attribute, unsigned long offsetInBytes, unsigned long strideInBytes) { eVertexBufferAttributeType elementType = GetType( attribute.Type() ); eVertexBufferAttributeDataType dataType = GetDataType( attribute.DataType() ); unsigned long dataTypeSize = GetDataTypeSize(dataType); AddVertexBufferAttribute(elementType, dataType, offsetInBytes, strideInBytes); int numberOfVerts = attribute.NumValues(); return numberOfVerts * static_cast<int>(dataTypeSize); }
bool OdbcCommand::BindParameters() { for (auto itr = m_params.begin(); itr != m_params.end(); itr++) { auto param = itr->second; if (!SQL_SUCCEEDED(SQLBindParameter(m_hStmt, itr->first + 1, param->GetParameterType(), param->GetCDataType(), param->GetDataType(), param->GetDataTypeSize(), 0, param->GetAddress(), param->GetDataTypeSize(), param->GetCBValue()))) { if (m_odbcConnection != NULL) m_szError = m_odbcConnection->ReportSQLError(SQL_HANDLE_STMT, m_hStmt, _T("SQLBindParameter"), _T("Failed to bind parameter.")); else m_szError = OdbcConnection::GetSQLError(SQL_HANDLE_STMT, m_hStmt); Close(); return false; } } return true; }
unsigned long tVertexDescription::VertexSize() const { unsigned long size = 0; unsigned long numVertexElements = m_VertexAttributeList.size(); for (unsigned long index = 0; index < numVertexElements; ++index) { size += GetDataTypeSize(m_VertexAttributeList[index].dataType); } return size; }
// ============================================================================ // >> x86MsStdcall // ============================================================================ x86MsStdcall::x86MsStdcall(std::vector<DataType_t> vecArgTypes, DataType_t returnType, int iAlignment) : ICallingConvention(vecArgTypes, returnType, iAlignment) { int iSize = GetDataTypeSize(m_returnType); if (iSize > 4) { m_pReturnBuffer = malloc(iSize); } else { m_pReturnBuffer = NULL; } }
void GlslGeneratorInstance::PrintUniforms() { // uniform-буферы и переменные // отсортировать их struct Sorter { bool operator()(const std::pair<UniformGroup*, UniformNode*>& a, const std::pair<UniformGroup*, UniformNode*>& b) const { int slotA = a.first->GetSlot(); int slotB = b.first->GetSlot(); return slotA < slotB || (slotA == slotB && a.second->GetOffset() < b.second->GetOffset()); } }; std::sort(uniforms.begin(), uniforms.end(), Sorter()); // удалить дубликаты uniforms.resize(std::unique(uniforms.begin(), uniforms.end()) - uniforms.begin()); // вывести буферы for(size_t i = 0; i < uniforms.size(); ) { size_t j; for(j = i + 1; j < uniforms.size() && uniforms[j].first == uniforms[i].first; ++j); int slot = uniforms[i].first->GetSlot(); // print header, if needed if(supportUniformBuffers) text << "layout(std140) uniform " << uniformBufferPrefix << slot << "\n{\n"; // текущее смещение от начала буфера int currentOffset = 0; // вывести переменные for(size_t k = i; k < j; ++k) { UniformNode* uniformNode = uniforms[k].second; DataType valueType = uniformNode->GetValueType(); int offset = uniformNode->GetOffset(); int count = uniformNode->GetCount(); int valueSize = GetDataTypeSize(valueType); // переменная должна лежать на границе float'а, как минимум if(offset % sizeof(float)) THROW("Wrong variable offset: should be on 4-byte boundary"); // если по умолчанию переменная попадёт в неправильное место, делаем пустые переменные, чтобы занять место // автоматический сдвиг if(currentOffset % sizeof(vec4) + valueSize > sizeof(vec4)) currentOffset = (currentOffset + sizeof(vec4) - 1) & ~(sizeof(vec4) - 1); // оставшийся сдвиг добиваем пустыми переменными (только если uniform буферы) if(supportUniformBuffers) { while(currentOffset < offset) { int newOffset = (currentOffset + sizeof(vec4)) & ~(sizeof(vec4) - 1); if(newOffset > offset) newOffset = offset; int size = (newOffset - currentOffset) / sizeof(float); static const char* dumpTypes[] = { "float", "vec2", "vec3", "vec4" }; text << '\t' << dumpTypes[size - 1] << " dump" << slot << '_' << currentOffset << '_' << size << ";\n"; currentOffset = newOffset; } } else currentOffset = offset; // печатаем определение переменной text << (supportUniformBuffers ? "\t" : "uniform "); PrintDataType(valueType); // имя переменной text << ' ' << uniformPrefix << slot << '_' << offset; // размер массива if(count > 1) text << '[' << count << ']'; // если массив, размер элемента должен быть кратен размеру vec4 if(count > 1 && valueSize % sizeof(vec4)) THROW("Size of element of array should be multiply of vec4 size"); // конец переменной text << ";\n"; // смещение для следующей переменной currentOffset += valueSize * count; } // ending of buffer if(supportUniformBuffers) text << "};\n"; i = j; } }
ECode CObjInfoList::AcquireDataTypeInfo( /* [in] */ CClsModule* clsModule, /* [in] */ TypeDescriptor* typeDesc, /* [out] */ IDataTypeInfo** dataTypeInfo, /* [in] */ Boolean isCheckLocalPtr) { if (!clsModule || !typeDesc || !dataTypeInfo) { return E_INVALID_ARGUMENT; } ECode ec = NOERROR; CLSModule* clsMod = clsModule->mClsMod; Int32 pointer = typeDesc->mPointer; if (typeDesc->mType == Type_alias) { ec = clsModule->AliasToOriginal(typeDesc, &typeDesc); if (FAILED(ec)) return ec; if (isCheckLocalPtr) pointer += typeDesc->mPointer; } CarDataType type = GetCarDataType(typeDesc->mType); if (isCheckLocalPtr) { if (type == CarDataType_Interface) { if (pointer > 1) { type = CarDataType_LocalPtr; pointer -= 1; } } else if (pointer > 0) { type = CarDataType_LocalPtr; } } *dataTypeInfo = NULL; //LocalPtr if (type == CarDataType_LocalPtr) { return g_objInfoList.AcquireLocalPtrInfo(clsModule, typeDesc, pointer, (ILocalPtrInfo **)dataTypeInfo); } //LocalType else if (type == CarDataType_LocalType) { MemorySize size = GetDataTypeSize(clsModule, typeDesc); return AcquireLocalTypeInfo(typeDesc->mType, size, dataTypeInfo); } //StructInfo else if (type == CarDataType_Struct) { StructDirEntry* structDir = getStructDirAddr(clsModule->mBase, clsModule->mClsMod->mStructDirs, typeDesc->mIndex); ec = AcquireStaticStructInfo(clsModule, structDir, (IInterface **)dataTypeInfo); } //InterfaceInfo else if (type == CarDataType_Interface) { ec = AcquireInterfaceInfo(clsModule, typeDesc->mIndex, (IInterface **)dataTypeInfo); } //EnumInfo else if (type == CarDataType_Enum) { EnumDirEntry* enumDir = getEnumDirAddr(clsModule->mBase, clsMod->mEnumDirs, typeDesc->mIndex); ec = AcquireStaticEnumInfo(clsModule, enumDir, (IInterface **)dataTypeInfo); } //CppVectorInfo else if (type == CarDataType_CppVector) { AutoPtr<IDataTypeInfo> elemInfo; ArrayDirEntry* arrayDir = getArrayDirAddr(clsModule->mBase, clsMod->mArrayDirs, typeDesc->mIndex); Int32 length = arrayDir->nElements; TypeDescriptor* type = &arrayDir->type; ec = AcquireDataTypeInfo(clsModule, type, (IDataTypeInfo**)&elemInfo, isCheckLocalPtr); if (FAILED(ec)) return ec; ec = AcquireCppVectorInfo(elemInfo, length, (ICppVectorInfo**)dataTypeInfo); } //CarArrayInfo else if (type == CarDataType_ArrayOf) { AutoPtr<IDataTypeInfo> elemInfo; ec = AcquireCarArrayElementTypeInfo(clsModule, typeDesc, (IDataTypeInfo**)&elemInfo); if (FAILED(ec)) return ec; ec = AcquireCarArrayInfo(type, elemInfo, (ICarArrayInfo**)dataTypeInfo); } //IntrinsicInfo else { CarDataType type = GetCarDataType(typeDesc->mType); if (type != CarDataType_LocalType) { UInt32 size = GetDataTypeSize(clsModule, typeDesc); ec = AcquireIntrinsicInfo(type, dataTypeInfo, size); } } return ec; }
void Hlsl11GeneratorInstance::PrintUniforms() { // uniform-буферы и переменные // отсортировать их struct Sorter { bool operator()(const std::pair<UniformGroup*, UniformNode*>& a, const std::pair<UniformGroup*, UniformNode*>& b) const { int slotA = a.first->GetSlot(); int slotB = b.first->GetSlot(); return slotA < slotB || slotA == slotB && a.second->GetOffset() < b.second->GetOffset(); } }; std::sort(uniforms.begin(), uniforms.end(), Sorter()); // удалить дубликаты uniforms.resize(std::unique(uniforms.begin(), uniforms.end()) - uniforms.begin()); // вывести буферы for(size_t i = 0; i < uniforms.size(); ) { size_t j; for(j = i + 1; j < uniforms.size() && uniforms[j].first == uniforms[i].first; ++j); // вывести заголовок int slot = uniforms[i].first->GetSlot(); text << "cbuffer CB" << slot << " : register(b" << slot << ")\n{\n"; // вывести переменные for(size_t k = i; k < j; ++k) { UniformNode* uniformNode = uniforms[k].second; DataType valueType = uniformNode->GetValueType(); int offset = uniformNode->GetOffset(); int count = uniformNode->GetCount(); // переменная должна лежать на границе float'а, как минимум if(offset % sizeof(float)) THROW("Wrong variable offset: should be on 4-byte boundary"); // печатаем определение переменной text << '\t'; PrintDataType(valueType); // имя переменной text << " u" << slot << '_' << offset; // размер массива if(count > 1) text << '[' << count << ']'; // если массив, размер элемента должен быть кратен размеру vec4 if(count > 1 && GetDataTypeSize(valueType) % sizeof(vec4)) THROW("Size of element of array should be multiply of vec4 size"); // регистр и положение в нём переменной text << " : packoffset(c" << (offset / sizeof(vec4)); // если переменная не начинается ровно на границе регистра, нужно дописать ещё первую компоненту регистра int registerOffset = offset % sizeof(vec4); if(registerOffset) { // получить размер данных int variableSize = GetDataTypeSize(valueType); // переменная не должна пересекать границу регистра if(registerOffset + variableSize > sizeof(vec4)) THROW("Variable should not intersect a register boundary"); // выложить нужную букву registerOffset /= sizeof(float); text << '.' << "xyzw"[registerOffset]; } // конец упаковки text << ")"; // конец переменной text << ";\n"; } // окончание text << "};\n"; i = j; } }
UInt32 GetDataTypeSize( /* [in] */ const CClsModule* clsModule, /* [in] */ TypeDescriptor* typeDesc) { UInt32 size = 0; CLSModule* module = clsModule->mClsMod; if (typeDesc->mType == Type_alias) { TypeDescriptor orgTypeDesc; _GetOriginalType(clsModule, typeDesc, &orgTypeDesc); typeDesc = &orgTypeDesc; } if (typeDesc->mPointer) { return sizeof(void *); } ArrayDirEntry* arrayDir = NULL; StructDirEntry* structDir = NULL; Int32 base = clsModule->mBase; switch (typeDesc->mType) { case Type_Char16: size = sizeof(Char16); break; case Type_Char32: size = sizeof(Char32); break; case Type_Int8: size = sizeof(Int8); break; case Type_Int16: size = sizeof(Int16); break; case Type_Int32: size = sizeof(Int32); break; case Type_Int64: size = sizeof(Int64); break; case Type_UInt16: size = sizeof(UInt16); break; case Type_UInt32: size = sizeof(UInt32); break; case Type_UInt64: size = sizeof(UInt64); break; case Type_Byte: size = sizeof(Byte); break; case Type_Boolean: size = sizeof(Boolean); break; case Type_EMuid: size = sizeof(EMuid); break; case Type_Float: size = sizeof(float); break; case Type_Double: size = sizeof(double); break; case Type_PVoid: size = 4; break; case Type_ECode: size = sizeof(ECode); break; case Type_EGuid: size = sizeof(ClassID); break; case Type_EventHandler: size = sizeof(EventHandler); break; case Type_String: // [in] String (in car) --> /* [in] */ const String& (in c++), so should be sizeof(String*) size = sizeof(String*); break; case Type_interface: size = sizeof(PInterface); break; case Type_struct: structDir = getStructDirAddr(base, module->mStructDirs, typeDesc->mIndex); size = adjustStructDescAddr(base, structDir->mDesc)->nAlignSize; break; case Type_Array: arrayDir = getArrayDirAddr(base, module->mArrayDirs, typeDesc->mIndex); size = GetDataTypeSize(clsModule, &arrayDir->type) * arrayDir->nElements; break; case Type_enum: size = sizeof(int); break; case Type_ArrayOf: size = GetDataTypeSize(clsModule, adjustNestedTypeAddr(base, typeDesc->mNestedType)); break; // case Type_EzEnum: // size = sizeof(EzEnum); // break; case Type_alias: case Type_const: default: size = 0; } return size; }