#include "tier2/fileformats/json.h" #include "tier2/ifilesystem.h" #include "tier0/commandline.h" #include "tier0/mem.h" #include "helper.h" #define EXTERNAL "../../external/" #define GRAMMAR EXTERNAL"SPIRV-Headers/include/spirv/unified1/spirv.core.grammar.json" #define OUTPUT "rtlinker_gen.cpp" DECLARE_BUILD_STAGE(SpirvOperandsGen) { if (!filesystem2->ShouldRecompile(GRAMMAR, OUTPUT)) return 0; if (!filesystem2->ShouldRecompile(__FILE__, OUTPUT)) return 0; IFileHandle *pHandle = filesystem->Open(GRAMMAR, FILEMODE_READ); if (pHandle == NULL) return 0; const char *szContents = filesystem->ReadString(pHandle); filesystem->Close(pHandle); pHandle = filesystem->Open(OUTPUT, FILEMODE_WRITE); IJSONValue *pRoot = JSONManager()->ReadString(szContents); IJSONArray *instructions = pRoot->GetObject()->GetValue("instructions")->GetArray(); filesystem->PrintF( pHandle, "#include \"rtlinker_gen.h\"\n"); filesystem->PrintF( pHandle, "int SpvGetOperandCount( int op )\n{\nswitch ( op ) {\n"); for ( int i = 0; i < instructions->GetCount(); i++) { IJSONObject *op = instructions->GetParameter(i)->GetObject(); if (op->GetValue("operands")) filesystem->PrintF( pHandle, "case %.0f: return %u;\n", op->GetValue("opcode")->GetNumberValue(), op->GetValue("operands")->GetArray()->GetCount()); } filesystem->PrintF( pHandle, "default: break;\n}\nreturn 0;\n}\n"); filesystem->PrintF( pHandle, "void SpvGetOperands( int op, ESpirvOperandType *pTypes )\n{\nswitch ( op ) {\n"); for ( int i = 0; i < instructions->GetCount(); i++) { IJSONObject *op = instructions->GetParameter(i)->GetObject(); if (op->GetValue("operands")) { IJSONArray *operands = op->GetValue("operands")->GetArray(); filesystem->PrintF( pHandle, "case %.0f:\n", op->GetValue("opcode")->GetNumberValue()); for ( int o = 0; o < operands->GetCount(); o++ ) { CUtlString type = operands->GetParameter(o)->GetObject()->GetValue("kind")->GetStringValue(); if (type == "IdRef") filesystem->PrintF( pHandle, "pTypes[%u] = k_ESpirv_RefId;\n",o); else if (type == "IdResult") filesystem->PrintF( pHandle, "pTypes[%u] = k_ESpirv_ResultId;\n",o); else if (type == "IdResultType") filesystem->PrintF( pHandle, "pTypes[%u] = k_ESpirv_ResultTypeId;\n",o); else if (type == "IdScope") filesystem->PrintF( pHandle, "pTypes[%u] = k_ESpirv_ScopeId;\n",o); else if (type == "IdMemorySemantics") filesystem->PrintF( pHandle, "pTypes[%u] = k_ESpirv_MemorySemanticsId;\n",o); } filesystem->PrintF( pHandle, "break;\n"); } } filesystem->PrintF( pHandle, "default: break;\n}\n"); filesystem->PrintF( pHandle, "}\n"); filesystem->PrintF( pHandle, "void SpvGetOperandFlags( int op, ESpirvOperandFlags *pTypes )\n{\nswitch ( op ) {\n"); for ( int i = 0; i < instructions->GetCount(); i++) { IJSONObject *op = instructions->GetParameter(i)->GetObject(); if (op->GetValue("operands")) { IJSONArray *operands = op->GetValue("operands")->GetArray(); filesystem->PrintF( pHandle, "case %.0f:\n", op->GetValue("opcode")->GetNumberValue()); for ( int o = 0; o < operands->GetCount(); o++ ) { IJSONValue *q = operands->GetParameter(o)->GetObject()->GetValue("quantifier"); if (q == 0) { filesystem->PrintF( pHandle, "pTypes[%u] = k_ESpirvOperandFlags_None;\n",o); continue; } CUtlString type = q->GetStringValue(); if (type == NULL) filesystem->PrintF( pHandle, "pTypes[%u] = k_ESpirvOperandFlags_None;\n",o); if (type == "?") filesystem->PrintF( pHandle, "pTypes[%u] = k_ESpirvOperandFlags_Optional;\n",o); else if (type == "*") filesystem->PrintF( pHandle, "pTypes[%u] = k_ESpirvOperandFlags_Array;\n",o); } filesystem->PrintF( pHandle, "break;\n"); } } filesystem->PrintF( pHandle, "default: break;\n}\n"); filesystem->PrintF( pHandle, "}\n"); filesystem->Close( pHandle ); V_free((void*)szContents); return 0; }