#include "cgnv2rt.h" #include #include #include #include "cgbio.hpp" #include "cg.h" #include using namespace cgc::bio; class CgBaseType { public: CgBaseType() {_type = 0;} virtual ~CgBaseType() {} unsigned short _type; short _resourceIndex; unsigned short _resource; }; class CgArrayType : public CgBaseType { public: CgArrayType():_elementType(NULL) { _type = (unsigned char)(CG_ARRAY + 128); } virtual ~CgArrayType() { if (_elementType) delete _elementType; } CgBaseType *_elementType; unsigned char _dimensionCount; unsigned short _dimensionItemCountsOffset; }; class CgStructureType : public CgBaseType { public: class CgStructuralElement { public: char _name[256]; char _semantic[256]; CgBaseType *_type; unsigned short _flags; unsigned short _index; }; CgStructureType() { _type = (unsigned char)(CG_STRUCT + 128); _root = false; } virtual ~CgStructureType() { int i=0; int count = (int)_elements.size(); for (i=0;i _elements; bool _insideArray; bool _root; }; typedef struct { const char *name; int resIndex; } BINDLOCATION; #define CG_DATATYPE_MACRO(name, compiler_name, enum_name, base_enum, nrows, ncols,classname) \ classname , static int classnames[] = { #include "Cg/cg_datatypes.h" }; #define CG_DATATYPE_MACRO(name, compiler_name, enum_name, base_enum, nrows, ncols,classname) \ nrows , static int rows[] = { #include "Cg/cg_datatypes.h" }; typedef float _float4[4]; typedef struct { STL_NAMESPACE vector _resources; STL_NAMESPACE vector _defaultValuesIndices; STL_NAMESPACE vector _elfDefaultsIndices; STL_NAMESPACE vector _dimensions; STL_NAMESPACE vector _semanticIndices; } _CGNVCONTAINERS; static bool bIsVertexProgram = true; static int getStride(CgBaseType *type); static int getSizeofSubArray(_CGNVCONTAINERS &containers, int dimensionIndex, int dimensionCount, int endianness); static unsigned int stringTableFind( STL_NAMESPACE vector &stringTable, const char* str); static unsigned int stringTableAdd( STL_NAMESPACE vector &stringTable, const char* str ); static unsigned int stringTableAddUnique( STL_NAMESPACE vector &stringTable, const char* str ); template static size_t array_size(STL_NAMESPACE vector &array); template static void array_push(char* ¶meterOffset, STL_NAMESPACE vector &array); inline static unsigned int swap16(const unsigned int v); static unsigned short getFlags(CGenum var, CGenum dir, int no, bool is_referenced, bool is_shared, int paramIndex); static void fillStructureItems(_CGNVCONTAINERS &containers, CgStructureType *structure, int endianness, STL_NAMESPACE vector ¶meterEntries, STL_NAMESPACE vector ¶meterResources, STL_NAMESPACE vector &stringTable, unsigned short *arrayResourceIndex = NULL, unsigned short *arrayDefaultValueIndex = NULL); int convertNvToElfFromMemory(const void *sourceData, size_t size, int endianness, int constTableOffset, void **binaryShader, int *binarySize, STL_NAMESPACE vector &stringTable, STL_NAMESPACE vector &defaultValues) { _CGNVCONTAINERS containers; unsigned char elfEndianness = endianness; nvb_reader* nvbr = 0; bin_io::instance()->new_nvb_reader( &nvbr ); CGBIO_ERROR err = nvbr->loadFromString((const char*)sourceData,size); if (err != CGBIO_ERROR_NO_ERROR) return -1; bool doSwap = !(nvbr->endianness() == (HOST_ENDIANNESS)elfEndianness); CGprofile NVProfile = nvbr->profile(); if (NVProfile == (CGprofile)7005 ) NVProfile = CG_PROFILE_SCE_VP_RSX; if (NVProfile == (CGprofile)7006 ) NVProfile = CG_PROFILE_SCE_FP_RSX; if (NVProfile == CG_PROFILE_SCE_VP_TYPEB || NVProfile == CG_PROFILE_SCE_VP_RSX) { bIsVertexProgram = true; } else if (NVProfile == CG_PROFILE_SCE_FP_TYPEB || NVProfile == CG_PROFILE_SCE_FP_RSX) { bIsVertexProgram = false; } else { return -1; } CgProgramHeader cgShader; memset(&cgShader,0,sizeof(CgProgramHeader)); cgShader.profile = CNV2END((unsigned short) NVProfile); cgShader.compilerVersion = 0;//TODO if (bIsVertexProgram) { const CgBinaryVertexProgram *nvVertex = nvbr->vertex_program(); if (doSwap) { cgShader.instructionCount = ENDSWAP(nvVertex->instructionCount); cgShader.attributeInputMask = ENDSWAP(nvVertex->attributeInputMask); cgShader.vertexProgram.instructionSlot = ENDSWAP(nvVertex->instructionSlot); cgShader.vertexProgram.registerCount = ENDSWAP(nvVertex->registerCount); cgShader.vertexProgram.attributeOutputMask = ENDSWAP(nvVertex->attributeOutputMask); } else { cgShader.instructionCount = nvVertex->instructionCount; cgShader.attributeInputMask = nvVertex->attributeInputMask; cgShader.vertexProgram.instructionSlot = nvVertex->instructionSlot; cgShader.vertexProgram.registerCount = nvVertex->registerCount; cgShader.vertexProgram.attributeOutputMask = nvVertex->attributeOutputMask; } } else { const CgBinaryFragmentProgram *nvFragment = nvbr->fragment_program(); unsigned char flags; if (doSwap) { cgShader.instructionCount = ENDSWAP(nvFragment->instructionCount); cgShader.attributeInputMask = ENDSWAP(nvFragment->attributeInputMask); cgShader.fragmentProgram.partialTexType = ENDSWAP(nvFragment->partialTexType); cgShader.fragmentProgram.texcoordInputMask = ENDSWAP(nvFragment->texCoordsInputMask); cgShader.fragmentProgram.texcoord2d = ENDSWAP(nvFragment->texCoords2D); cgShader.fragmentProgram.texcoordCentroid = ENDSWAP(nvFragment->texCoordsCentroid); cgShader.fragmentProgram.registerCount = ENDSWAP(nvFragment->registerCount); flags = (nvFragment->outputFromH0 ? CGF_OUTPUTFROMH0 : 0) | (nvFragment->depthReplace ? CGF_DEPTHREPLACE : 0) | (nvFragment->pixelKill ? CGF_PIXELKILL : 0); } else { cgShader.instructionCount = nvFragment->instructionCount; cgShader.attributeInputMask = nvFragment->attributeInputMask; cgShader.fragmentProgram.partialTexType = nvFragment->partialTexType; cgShader.fragmentProgram.texcoordInputMask = nvFragment->texCoordsInputMask; cgShader.fragmentProgram.texcoord2d = nvFragment->texCoords2D; cgShader.fragmentProgram.texcoordCentroid = nvFragment->texCoordsCentroid; cgShader.fragmentProgram.registerCount = nvFragment->registerCount; flags = (nvFragment->outputFromH0 ? CGF_OUTPUTFROMH0 : 0) | (nvFragment->depthReplace ? CGF_DEPTHREPLACE : 0) | (nvFragment->pixelKill ? CGF_PIXELKILL : 0); } cgShader.fragmentProgram.flags = CNV2END(flags); } unsigned int *tmp = (unsigned int *)nvbr->ucode(); const char *ucode; unsigned int *buffer = NULL; if (doSwap) { int size = (int)nvbr->ucode_size()/sizeof(unsigned int); buffer = new unsigned int[size]; for (int i=0;iucode_size()/sizeof(unsigned int); buffer = new unsigned int[size]; for (int i=0;iucode_size(); CgStructureType root; root._insideArray = false; root._root = true; int paramIndex = -1; CgStructureType::CgStructuralElement *current = NULL; int embeddedConstants = 0; int rootChildIndex = -1; int i; for (i = 0; i < (int)nvbr->number_of_params(); i++) { CGtype type; CGresource res; CGenum var; int rin; const char *name; STL_NAMESPACE vector dv; STL_NAMESPACE vector ec; const char *sem; CGenum dir; int no; bool is_referenced; bool is_shared; nvbr->get_param( i, type, res, var, rin, &name, dv, ec, &sem, no, is_referenced, is_shared ); if (strlen(sem)>=2 && sem[0] == 'C') { const char *szSem = sem+1; while (*szSem != '\0') { if ( (*szSem) < '0' || (*szSem) > '9') break; szSem++; } if (*szSem == '\0') is_shared = 1; } const char *parameterName = name; const char *structureEnd = NULL; CgStructureType *container = &root; int done = 0; const char * structureStart = parameterName; while (!done && *structureStart) { structureEnd = strpbrk(structureStart, ".["); if (structureEnd) { if (*structureEnd == '[' && type >= CG_SAMPLER1D && type <= CG_SAMPLERCUBE) { const char *closed = strchr(structureEnd, ']'); const char *somethingElse = strpbrk(closed, ".["); if (!somethingElse) structureEnd = NULL; } } if (structureEnd == NULL) { structureEnd = structureStart + strlen(structureStart); done = 1; } char structName[256]; int length = (int)(structureEnd - structureStart); strncpy(structName, structureStart, length); structName[length] = '\0'; CgStructureType::CgStructuralElement *structuralElement = NULL; int j=0; int elementCount = (int)container->_elements.size(); for (j=0;j_elements[j]; if (!strcmp(structuralElement->_name,structName)) { if ( (no == -1 && (structuralElement->_flags & CGPF_GLOBAL)) || (no != -1 && !(structuralElement->_flags & CGPF_GLOBAL))) break; } } if (j==elementCount) { if (container == &root) { if (rootChildIndex != j) rootChildIndex = j; } container->_elements.resize(elementCount+1); structuralElement = &container->_elements[elementCount]; strncpy(structuralElement->_name,structName,sizeof(structuralElement->_name)); structuralElement->_name[sizeof(structuralElement->_name)-1] = '\0'; structuralElement->_flags = getFlags(var,dir,no,is_referenced,is_shared,paramIndex); int dimensionCount = 0; if (strncmp(sem, "COLOR", 5) == 0 || strncmp(sem, "NORMAL", 6) == 0) structuralElement->_flags |= CGP_NORMALIZE; int isStructure = (*structureEnd == '.'); if (*structureEnd == '[') { dimensionCount++; const char *arrayEnd = strchr(structureEnd,']')+1; while (*arrayEnd == '[') { arrayEnd = strchr(arrayEnd,']')+1; dimensionCount++; } if (*arrayEnd == '.') isStructure = true; } if (dimensionCount) { CgArrayType *arrayType = new CgArrayType; arrayType->_dimensionCount = dimensionCount; arrayType->_dimensionItemCountsOffset = (unsigned short)containers._dimensions.size(); int k; for (k=0;k_type = arrayType; if (isStructure) { container = new CgStructureType; container->_insideArray = true; arrayType->_elementType = container; } else { arrayType->_elementType = new CgBaseType; arrayType->_elementType->_type = type - CG_TYPE_START_ENUM; } arrayType->_elementType->_resource = res; arrayType->_elementType->_resourceIndex = -1; if (bIsVertexProgram && strlen(sem)>=2 && sem[0] == 'C') { const char *szSem = sem+1; while (*szSem != '\0') { if ( (*szSem) < '0' || (*szSem) > '9') break; szSem++; } if (*szSem == '\0') { is_shared = 1; int registerIndex = atoi(sem+1); structuralElement->_flags |= CGP_CONTIGUOUS; structuralElement->_flags |= CGPF_SHARED; structuralElement->_type->_resourceIndex = registerIndex; } else structuralElement->_type->_resourceIndex = (int)containers._resources.size(); } else structuralElement->_type->_resourceIndex = (int)containers._resources.size(); structuralElement->_type->_resource = res; } else { if (isStructure) { bool insideArray = container->_insideArray; container = new CgStructureType; container->_insideArray = insideArray; structuralElement->_type = container; } else { structuralElement->_type = new CgBaseType; structuralElement->_type->_type = type - CG_TYPE_START_ENUM; structuralElement->_type->_resource = res; if (classnames[structuralElement->_type->_type-1] == CG_PARAMETERCLASS_MATRIX) { if (bIsVertexProgram) { structuralElement->_type->_resourceIndex = (short)rin; } else structuralElement->_type->_resourceIndex = (int)containers._resources.size(); } else { if (!container->_insideArray) { if (bIsVertexProgram) structuralElement->_type->_resourceIndex = rin; else { if (structuralElement->_flags & CGPV_VARYING) structuralElement->_type->_resourceIndex = -1; else { structuralElement->_type->_resourceIndex = (int)containers._resources.size(); containers._resources.push_back(CNV2END((unsigned short)rin)); int size = (int)ec.size(); containers._resources.push_back(CNV2END((unsigned short)size)); int k; for (k=0;k_type->_resourceIndex = (short)-1; structuralElement->_type->_resource = (unsigned short)res; } } } } } else { if (structuralElement->_type->_type == CG_STRUCT+128) { container = (CgStructureType*)structuralElement->_type; } else if (structuralElement->_type->_type == CG_ARRAY+128) { CgArrayType *arrayType = (CgArrayType *)structuralElement->_type; if (arrayType->_elementType->_type >128 ) { container = (CgStructureType*)arrayType->_elementType; } } } if (dv.size()) { int size = (int)containers._defaultValuesIndices.size(); if (!size || (containers._defaultValuesIndices[size-2] != CNV2END((unsigned short)(rootChildIndex)))) { containers._defaultValuesIndices.push_back(CNV2END((unsigned short)(rootChildIndex))); containers._defaultValuesIndices.push_back(CNV2END((unsigned short)defaultValues.size())); } } if (container->_insideArray && done) { if (is_referenced) { bool sharedContiguous = (structuralElement->_flags & CGPF_SHARED) && (structuralElement->_flags & CGP_CONTIGUOUS); structuralElement->_flags = getFlags(var,dir,no,is_referenced,is_shared,paramIndex); if (sharedContiguous) structuralElement->_flags |= ( CGP_CONTIGUOUS | CGPF_SHARED); } if (bIsVertexProgram) { if (!is_shared) containers._resources.push_back(CNV2END((unsigned short)rin)); } else { if (structuralElement->_flags & CGPV_VARYING) containers._resources.push_back(CNV2END((unsigned short)rin)); else { containers._resources.push_back(CNV2END((unsigned short)rin)); int size = (int)ec.size(); containers._resources.push_back(CNV2END((unsigned short)size)); int k; for (k=0;k_type; if (itemType->_type >= 128) { arrayType = (CgArrayType *)itemType; int dimensionCount = 0; while (*arrayStart == '[' && dimensionCount_dimensionCount) { arrayEnd = strchr(arrayStart+1,']'); int length =(int)(arrayEnd - arrayStart - 1); char indexString[16]; strncpy(indexString,arrayStart+1,length); indexString[length] = '\0'; int index = atoi(indexString); int dim = CNV2END(containers._dimensions[arrayType->_dimensionItemCountsOffset + dimensionCount]); if ((index+1) > dim) containers._dimensions[arrayType->_dimensionItemCountsOffset + dimensionCount] = CNV2END((short)(index+1)); arrayCellIndex += index*getSizeofSubArray(containers,arrayType->_dimensionItemCountsOffset + dimensionCount,arrayType->_dimensionCount - dimensionCount -1,endianness); arrayStart = arrayEnd+1; dimensionCount++; } structureEnd = arrayStart; itemType = arrayType->_elementType; if (itemType->_type<128) { int rowCount = rows[itemType->_type-1]; if (!rowCount) { bool sharedContiguous = (structuralElement->_flags & CGPF_SHARED) && (structuralElement->_flags & CGP_CONTIGUOUS); if (!bIsVertexProgram || !sharedContiguous) { containers._resources.push_back(CNV2END((unsigned short)rin)); } if (!bIsVertexProgram) { int size = (int)ec.size(); containers._resources.push_back(CNV2END((unsigned short)size)); int k; for (k=0;k_type <128) { if (structuralElement != current) { embeddedConstants = 0; current = structuralElement; } int length =(int)(arrayEnd - arrayStart - 1); char indexString[16]; strncpy(indexString,arrayStart+1,length); indexString[length] = '\0'; if (bIsVertexProgram) { if (arrayType) { bool sharedContiguous = (structuralElement->_flags & CGPF_SHARED) && (structuralElement->_flags & CGP_CONTIGUOUS); if (!sharedContiguous) { containers._resources.push_back(CNV2END((unsigned short)rin)); } } } else { containers._resources.push_back(CNV2END((unsigned short)rin)); int size = (int)ec.size(); containers._resources.push_back(CNV2END((unsigned short)size)); int k; for (k=0;k_flags & CGPF_SHARED) && (structuralElement->_flags & CGP_CONTIGUOUS); unsigned short flag = getFlags(var,dir,no,is_referenced,is_shared,paramIndex); structuralElement->_flags = flag; if (sharedContiguous) structuralElement->_flags |= ( CGP_CONTIGUOUS | CGPF_SHARED); structuralElement->_type->_resource = res; if (arrayType) arrayType->_elementType->_resource = res; } } if (done && dv.size()) { for ( int jj = 0; jj < (int)dv.size(); ++jj ) { defaultValues.push_back(dv[jj]); } } if (done) { if (strlen(sem)) { strncpy(structuralElement->_semantic,sem,sizeof(structuralElement->_semantic)); } else structuralElement->_semantic[0] = '\0'; } structureStart = structureEnd+1; } } nvbr->release(); bin_io::delete_instance(); STL_NAMESPACE vector parameterEntries; STL_NAMESPACE vector parameterResources; fillStructureItems(containers,&root,endianness,parameterEntries,parameterResources,stringTable); CgParameterTableHeader header; memset(&header,0,sizeof(CgParameterTableHeader)); header.entryCount = (unsigned short)parameterEntries.size(); header.resourceTableOffset = sizeof(CgParameterTableHeader) + (unsigned short)(parameterEntries.size()*sizeof(parameterEntries[0]) + parameterResources.size()*sizeof(parameterResources[0])); header.defaultValueIndexTableOffset = header.resourceTableOffset + (unsigned short)containers._resources.size() * sizeof(containers._resources[0]); header.defaultValueIndexCount = (unsigned short)containers._elfDefaultsIndices.size()/2; header.semanticIndexTableOffset = header.defaultValueIndexTableOffset + (unsigned short)containers._elfDefaultsIndices.size() * sizeof (containers._elfDefaultsIndices[0]); header.semanticIndexCount = (unsigned short)containers._semanticIndices.size(); header.entryCount = CNV2END(header.entryCount); header.resourceTableOffset = CNV2END(header.resourceTableOffset); header.defaultValueIndexTableOffset = CNV2END(header.defaultValueIndexTableOffset); header.defaultValueIndexCount = CNV2END(header.defaultValueIndexCount); header.semanticIndexTableOffset = CNV2END(header.semanticIndexTableOffset); header.semanticIndexCount = CNV2END(header.semanticIndexCount); size_t parameterTableSize = sizeof(CgParameterTableHeader); parameterTableSize += array_size(parameterEntries); parameterTableSize += array_size(parameterResources); parameterTableSize += array_size(containers._resources); parameterTableSize += array_size(containers._elfDefaultsIndices); parameterTableSize += array_size(containers._semanticIndices); int ucodeOffset = (((sizeof(CgProgramHeader)-1)/16)+1)*16; size_t programSize = ucodeOffset + ucodeSize + parameterTableSize; char *program = new char[programSize]; memcpy(program,&cgShader,sizeof(CgProgramHeader)); if (ucodeOffset-sizeof(CgProgramHeader)) memset(program+sizeof(CgProgramHeader),0,ucodeOffset-sizeof(CgProgramHeader)); memcpy(program + ucodeOffset,ucode,ucodeSize); if (!bIsVertexProgram && doSwap) delete[] buffer; else delete[] buffer; char *parameterOffset = program + ucodeOffset + ucodeSize; memcpy(parameterOffset,&header,sizeof(CgParameterTableHeader)); parameterOffset += sizeof(CgParameterTableHeader); array_push(parameterOffset, parameterEntries); array_push(parameterOffset, parameterResources); array_push(parameterOffset, containers._resources); array_push(parameterOffset, containers._elfDefaultsIndices); array_push(parameterOffset, containers._semanticIndices); *binarySize = (int)programSize; *binaryShader = program; return 0; } int convertNvToElfFreeBinaryShader(void *binaryShader) { char *program = (char *)binaryShader; delete[] program; return 0; } static void pushbackUnsignedShort(STL_NAMESPACE vector ¶meterResources, unsigned short value) { size_t size = parameterResources.size(); parameterResources.resize(size + 2); *((unsigned short*)¶meterResources[size]) = value; } static void fillStructureItems(_CGNVCONTAINERS &containers, CgStructureType *structure, int endianness, STL_NAMESPACE vector ¶meterEntries,STL_NAMESPACE vector ¶meterResources, STL_NAMESPACE vector &stringTable, unsigned short *arrayResourceIndex, unsigned short *arrayDefaultValueIndex) { unsigned char elfEndianness = endianness; int currentDefaultIndex = 0; int count = (int)structure->_elements.size(); int i; for (i=0;i_elements[i]; size_t size = parameterEntries.size(); parameterEntries.resize(size+1); CgParameterEntry *parameterEntry = ¶meterEntries[size]; parameterEntry->nameOffset = CNV2END((int)stringTableAddUnique(stringTable, structuralElement->_name)); if (structuralElement->_semantic[0]) { CgParameterSemantic semantic; semantic.entryIndex = CNV2END((unsigned short)size); semantic.reserved = 0; semantic.semanticOffset = CNV2END((int)stringTableAddUnique(stringTable, structuralElement->_semantic)); containers._semanticIndices.push_back(semantic); } parameterEntry->flags = CNV2END(structuralElement->_flags); unsigned short typeIndex = ((unsigned short)parameterResources.size()); parameterEntry->typeIndex = CNV2END(typeIndex); CgBaseType *itemType = structuralElement->_type; unsigned short _resource = itemType->_resource; unsigned short _resourceIndex = itemType->_resourceIndex; int parameterEntryIndex; if (itemType->_type-128 == CG_ARRAY) { CgArrayType *arrayType = (CgArrayType *)structuralElement->_type; int arraySize = getSizeofSubArray(containers,arrayType->_dimensionItemCountsOffset,arrayType->_dimensionCount,endianness); itemType = arrayType->_elementType; unsigned short arrayFlag = CGP_ARRAY; parameterEntry->flags |= CNV2END(arrayFlag); parameterResources.resize(typeIndex+sizeof(CgParameterArray)); CgParameterArray *parameterArray = (CgParameterArray *)(¶meterResources[typeIndex]); if (itemType->_type-128 == CG_STRUCT ) parameterArray->arrayType = CNV2END((unsigned short)CG_STRUCT); else parameterArray->arrayType = CNV2END(itemType->_type+128); parameterArray->dimensionCount = CNV2END((unsigned short)arrayType->_dimensionCount); int j; for (j=0;j_dimensionCount;j++) { pushbackUnsignedShort(parameterResources,(unsigned short)containers._dimensions[arrayType->_dimensionItemCountsOffset+j]); } if (arrayType->_dimensionCount&1) pushbackUnsignedShort(parameterResources,CNV2END((unsigned short)0)); if (itemType->_type-128 == CG_STRUCT ) { unsigned short unrolledFlag = CGP_UNROLLED; parameterEntry->flags |= CNV2END(unrolledFlag); CgStructureType *structureType = (CgStructureType*)itemType; int k; unsigned short _arrayResourceIndex = (unsigned short)(arrayType->_resourceIndex); unsigned short _arrayDefaultValueIndex = 0; bool hasDefaults = false; if (structure->_root && containers._defaultValuesIndices.size()) { if (containers._defaultValuesIndices[currentDefaultIndex*2] == CNV2END((unsigned short)i)) { hasDefaults = true; _arrayDefaultValueIndex = containers._defaultValuesIndices[currentDefaultIndex*2+1]; } } for (k=0;k_name,k); parameterArrayEntry.nameOffset = CNV2END((int)stringTableAddUnique(stringTable, buffer)); parameterArrayEntry.flags = CNV2END(structuralElement->_flags); unsigned short structureFlag = CGP_STRUCTURE; parameterArrayEntry.flags |= CNV2END(structureFlag); unsigned short arrayEntryTypeIndex = (unsigned short)parameterResources.size(); parameterResources.resize(arrayEntryTypeIndex+sizeof(CgParameterStructure)); parameterArrayEntry.typeIndex = CNV2END(arrayEntryTypeIndex); CgParameterStructure *parameterStructure = (CgParameterStructure*)(¶meterResources[arrayEntryTypeIndex]); parameterStructure->memberCount = CNV2END((unsigned short)structureType->_elements.size()); parameterStructure->reserved = CNV2END((unsigned short)0); if (hasDefaults) fillStructureItems(containers,structureType,endianness,parameterEntries,parameterResources,stringTable,&_arrayResourceIndex,&_arrayDefaultValueIndex); else fillStructureItems(containers,structureType,endianness,parameterEntries,parameterResources,stringTable,&_arrayResourceIndex); } if (hasDefaults) { currentDefaultIndex++; } continue; } else { size_t size = parameterEntries.size(); parameterEntries.resize(size+1); parameterEntry = ¶meterEntries[size]; parameterEntry->nameOffset = CNV2END(0); parameterEntry->flags = CNV2END(structuralElement->_flags); typeIndex = ((unsigned short)parameterResources.size()); parameterEntry->typeIndex = CNV2END(typeIndex); parameterEntryIndex = (int)size - 1; } } else { unsigned short contiguousFlag = CGP_CONTIGUOUS; parameterEntry->flags |= CNV2END(contiguousFlag); size_t size = parameterEntries.size(); parameterEntryIndex = (int)size - 1; } if (itemType->_type<128) { parameterResources.resize(typeIndex+sizeof(CgParameterResource)); CgParameterResource *parameterResource = (CgParameterResource*)(¶meterResources[typeIndex]); if (itemType->_type + CG_TYPE_START_ENUM == CG_BOOL) { parameterResource->type = CNV2END((unsigned short)CGP_SCF_BOOL); } else { parameterResource->type = CNV2END((unsigned short)(itemType->_type + CG_TYPE_START_ENUM)); } if ((structuralElement->_flags & CGPV_MASK) == CGPV_UNIFORM || (structuralElement->_flags & CGPV_MASK) == CGPV_CONSTANT) { if (itemType->_type +CG_TYPE_START_ENUM >= CG_SAMPLER1D && itemType->_type +CG_TYPE_START_ENUM<= CG_SAMPLERCUBE) parameterResource->resource = CNV2END(_resource); else { if (arrayResourceIndex) { unsigned short tmp = *arrayResourceIndex; unsigned short localflags = CNV2END(parameterEntry->flags); if (!bIsVertexProgram) { parameterResource->resource = CNV2END(tmp); int embeddedConstantCount = CNV2END(containers._resources[tmp+1]); (*arrayResourceIndex) = tmp+1+1+embeddedConstantCount; if (embeddedConstantCount == 0 && (CNV2END(containers._resources[tmp]) == 0)) { if (parameterResource->resource == 0xffff) localflags &= ~CGPF_REFERENCED; } } else { if (structuralElement->_flags & CGPF_SHARED) { int stride = getStride(itemType); parameterResource->resource = *arrayResourceIndex; (*arrayResourceIndex) = tmp+stride; } else { parameterResource->resource = containers._resources[tmp]; (*arrayResourceIndex) = tmp+1; } if (parameterResource->resource == 0xffff) localflags &= ~CGPF_REFERENCED; } parameterEntry->flags = CNV2END(localflags); } else parameterResource->resource = CNV2END(_resourceIndex); } } else { parameterResource->resource = CNV2END(itemType->_resource); } if (containers._defaultValuesIndices.size()) { if (structure->_root) { if (currentDefaultIndex < (int)(containers._defaultValuesIndices.size()/2) && containers._defaultValuesIndices[currentDefaultIndex*2] == CNV2END((unsigned short)i)) { containers._elfDefaultsIndices.push_back(CNV2END((unsigned short)(parameterEntryIndex))); containers._elfDefaultsIndices.push_back(containers._defaultValuesIndices[currentDefaultIndex*2+1]); currentDefaultIndex++; } } else if (arrayDefaultValueIndex) { containers._elfDefaultsIndices.push_back(CNV2END((unsigned short)(parameterEntryIndex))); containers._elfDefaultsIndices.push_back(*arrayDefaultValueIndex); int typeRegisterCount = getStride(itemType); *arrayDefaultValueIndex = CNV2END( (unsigned short)((CNV2END((*arrayDefaultValueIndex)))+typeRegisterCount*4)); } } } else if (itemType->_type == CG_STRUCT + 128) { unsigned short structureFlag = CGP_STRUCTURE; parameterEntry->flags |= CNV2END(structureFlag); CgStructureType *structureType = (CgStructureType*)itemType; parameterResources.resize(typeIndex+sizeof(CgParameterStructure)); CgParameterStructure *parameterStructure = (CgParameterStructure*)(¶meterResources[typeIndex]); parameterStructure->memberCount = CNV2END((unsigned short)structureType->_elements.size()); parameterStructure->reserved = CNV2END((unsigned short)0); fillStructureItems(containers,structureType,endianness,parameterEntries,parameterResources,stringTable); if (containers._defaultValuesIndices.size() && structure->_root) { if (currentDefaultIndex < (int)(containers._defaultValuesIndices.size()/2) && containers._defaultValuesIndices[currentDefaultIndex*2] == CNV2END((unsigned short)i)) { containers._elfDefaultsIndices.push_back(CNV2END((unsigned short)(parameterEntryIndex))); containers._elfDefaultsIndices.push_back(containers._defaultValuesIndices[currentDefaultIndex*2+1]); currentDefaultIndex++; } } } } } static int getStride(CgBaseType *type) { if (type->_type <128) { if (classnames[type->_type-1] == CG_PARAMETERCLASS_MATRIX) return rows[type->_type-1]; else return 1; } else { if (type->_type == CG_STRUCT + 128) { CgStructureType *structureType = (CgStructureType *)type; int res = 0; int i; int count = (int)structureType->_elements.size(); for (i=0;i_elements[i]._type); return res; } else { return -9999999; } } } static int getSizeofSubArray(_CGNVCONTAINERS &containers, int dimensionIndex, int dimensionCount, int endianness) { unsigned char elfEndianness = endianness; int res = 1; int i; for (i=0;i static size_t array_size(STL_NAMESPACE vector &array) { return (unsigned int)array.size()*sizeof(array[0]); } template static void array_push(char* ¶meterOffset, STL_NAMESPACE vector &array) { size_t dataSize = array.size()*sizeof(array[0]); memcpy(parameterOffset,&array[0],dataSize); parameterOffset += dataSize; } unsigned int inline static swap16(const unsigned int v) { return (v>>16) | (v<<16); } unsigned short getFlags(CGenum var, CGenum dir, int no, bool is_referenced, bool is_shared, int paramIndex) { (void)paramIndex; unsigned short flags = 0; if (var == CG_VARYING) flags |= CGPV_VARYING; else if (var == CG_UNIFORM) flags |= CGPV_UNIFORM; else if (var == CG_CONSTANT) flags |= CGPV_CONSTANT; else if (var == CG_MIXED) flags |= CGPV_MIXED; if (is_referenced) flags |= CGPF_REFERENCED; if (is_shared) flags |= CGPF_SHARED; if (no == -1) flags |= CGPF_GLOBAL; else if (no == -2) flags |= CGP_INTERNAL; else { paramIndex = no; } return flags; }