static bool TestFile (glslopt_ctx* ctx, bool vertex, const std::string& testName, const std::string& inputPath, const std::string& hirPath, const std::string& outputPath, bool gles, bool doCheckGLSL) { std::string input; if (!ReadStringFromFile (inputPath.c_str(), input)) { printf ("\n %s: failed to read input file\n", testName.c_str()); return false; } if (doCheckGLSL) { if (!CheckGLSL (vertex, gles, testName, "input", input.c_str())) return false; } if (gles) { if (vertex) MassageVertexForGLES (input); else MassageFragmentForGLES (input); } bool res = true; glslopt_shader_type type = vertex ? kGlslOptShaderVertex : kGlslOptShaderFragment; glslopt_shader* shader = glslopt_optimize (ctx, type, input.c_str(), 0); bool optimizeOk = glslopt_get_status(shader); if (optimizeOk) { std::string textHir = glslopt_get_raw_output (shader); std::string textOpt = glslopt_get_output (shader); std::string outputHir; ReadStringFromFile (hirPath.c_str(), outputHir); std::string outputOpt; ReadStringFromFile (outputPath.c_str(), outputOpt); if (textHir != outputHir) { // write output FILE* f = fopen (hirPath.c_str(), "wb"); if (!f) { printf ("\n %s: can't write to IR file!\n", testName.c_str()); } else { fwrite (textHir.c_str(), 1, textHir.size(), f); fclose (f); } printf ("\n %s: does not match raw output\n", testName.c_str()); res = false; } if (textOpt != outputOpt) { // write output FILE* f = fopen (outputPath.c_str(), "wb"); if (!f) { printf ("\n %s: can't write to optimized file!\n", testName.c_str()); } else { fwrite (textOpt.c_str(), 1, textOpt.size(), f); fclose (f); } printf ("\n %s: does not match optimized output\n", testName.c_str()); res = false; } if (res && doCheckGLSL && !CheckGLSL (vertex, gles, testName, "raw", textHir.c_str())) res = false; if (res && doCheckGLSL && !CheckGLSL (vertex, gles, testName, "optimized", textOpt.c_str())) res = false; } else { printf ("\n %s: optimize error: %s\n", testName.c_str(), glslopt_get_log(shader)); res = false; } glslopt_shader_delete (shader); return res; }
static bool TestFile (glslopt_ctx* ctx, bool vertex, const std::string& testName, const std::string& inputPath, const std::string& outputPath, bool gles, bool doCheckGLSL, bool doCheckMetal) { std::string input; if (!ReadStringFromFile (inputPath.c_str(), input)) { printf ("\n %s: failed to read input file\n", testName.c_str()); return false; } if (doCheckGLSL) { if (!CheckGLSL (vertex, gles, testName, "input", input.c_str())) return false; } if (gles) { if (vertex) MassageVertexForGLES (input); else MassageFragmentForGLES (input); } bool res = true; glslopt_shader_type type = vertex ? kGlslOptShaderVertex : kGlslOptShaderFragment; glslopt_shader* shader = glslopt_optimize (ctx, type, input.c_str(), 0); bool optimizeOk = glslopt_get_status(shader); if (optimizeOk) { std::string textHir = glslopt_get_raw_output (shader); std::string textOpt = glslopt_get_output (shader); // append stats char buffer[1000]; int statsAlu, statsTex, statsFlow; glslopt_shader_get_stats (shader, &statsAlu, &statsTex, &statsFlow); sprintf(buffer, "\n// stats: %i alu %i tex %i flow\n", statsAlu, statsTex, statsFlow); textOpt += buffer; // append inputs const int inputCount = glslopt_shader_get_input_count (shader); if (inputCount > 0) { sprintf(buffer, "// inputs: %i\n", inputCount); textOpt += buffer; } for (int i = 0; i < inputCount; ++i) { const char* parName; glslopt_basic_type parType; glslopt_precision parPrec; int parVecSize, parMatSize, parArrSize, location; glslopt_shader_get_input_desc(shader, i, &parName, &parType, &parPrec, &parVecSize, &parMatSize, &parArrSize, &location); if (location >= 0) sprintf(buffer, "// #%i: %s (%s %s) %ix%i [%i] loc %i\n", i, parName, kGlslPrecNames[parPrec], kGlslTypeNames[parType], parVecSize, parMatSize, parArrSize, location); else sprintf(buffer, "// #%i: %s (%s %s) %ix%i [%i]\n", i, parName, kGlslPrecNames[parPrec], kGlslTypeNames[parType], parVecSize, parMatSize, parArrSize); textOpt += buffer; } // append uniforms const int uniformCount = glslopt_shader_get_uniform_count (shader); const int uniformSize = glslopt_shader_get_uniform_total_size (shader); if (uniformCount > 0) { sprintf(buffer, "// uniforms: %i (total size: %i)\n", uniformCount, uniformSize); textOpt += buffer; } for (int i = 0; i < uniformCount; ++i) { const char* parName; glslopt_basic_type parType; glslopt_precision parPrec; int parVecSize, parMatSize, parArrSize, location; glslopt_shader_get_uniform_desc(shader, i, &parName, &parType, &parPrec, &parVecSize, &parMatSize, &parArrSize, &location); if (location >= 0) sprintf(buffer, "// #%i: %s (%s %s) %ix%i [%i] loc %i\n", i, parName, kGlslPrecNames[parPrec], kGlslTypeNames[parType], parVecSize, parMatSize, parArrSize, location); else sprintf(buffer, "// #%i: %s (%s %s) %ix%i [%i]\n", i, parName, kGlslPrecNames[parPrec], kGlslTypeNames[parType], parVecSize, parMatSize, parArrSize); textOpt += buffer; } // append textures const int textureCount = glslopt_shader_get_texture_count (shader); if (textureCount > 0) { sprintf(buffer, "// textures: %i\n", textureCount); textOpt += buffer; } for (int i = 0; i < textureCount; ++i) { const char* parName; glslopt_basic_type parType; glslopt_precision parPrec; int parVecSize, parMatSize, parArrSize, location; glslopt_shader_get_texture_desc(shader, i, &parName, &parType, &parPrec, &parVecSize, &parMatSize, &parArrSize, &location); if (location >= 0) sprintf(buffer, "// #%i: %s (%s %s) %ix%i [%i] loc %i\n", i, parName, kGlslPrecNames[parPrec], kGlslTypeNames[parType], parVecSize, parMatSize, parArrSize, location); else sprintf(buffer, "// #%i: %s (%s %s) %ix%i [%i]\n", i, parName, kGlslPrecNames[parPrec], kGlslTypeNames[parType], parVecSize, parMatSize, parArrSize); textOpt += buffer; } std::string outputOpt; ReadStringFromFile (outputPath.c_str(), outputOpt); if (res && doCheckMetal && !CheckMetal (vertex, gles, testName, "metal", textOpt.c_str())) res = false; if (textOpt != outputOpt) { // write output FILE* f = fopen (outputPath.c_str(), "wb"); if (!f) { printf ("\n %s: can't write to optimized file!\n", testName.c_str()); } else { fwrite (textOpt.c_str(), 1, textOpt.size(), f); fclose (f); } printf ("\n %s: does not match optimized output\n", testName.c_str()); res = false; } if (res && doCheckGLSL && !CheckGLSL (vertex, gles, testName, "raw", textHir.c_str())) res = false; if (res && doCheckGLSL && !CheckGLSL (vertex, gles, testName, "optimized", textOpt.c_str())) res = false; } else { printf ("\n %s: optimize error: %s\n", testName.c_str(), glslopt_get_log(shader)); res = false; } glslopt_shader_delete (shader); return res; }
static bool TestFile (TestRun type, const std::string& inputPath, const std::string& outputPath, const char* entryPoint, ETargetVersion version, unsigned options, bool doCheckGLSL) { assert(version != ETargetVersionCount); std::string input; if (!ReadStringFromFile (inputPath.c_str(), input)) { printf (" failed to read input file\n"); return false; } ShHandle parser = Hlsl2Glsl_ConstructCompiler (kTypeLangs[type]); const char* sourceStr = input.c_str(); bool res = true; if (kDumpShaderAST) options |= ETranslateOpIntermediate; IncludeContext includeCtx; includeCtx.currentFolder = inputPath.substr(0, inputPath.rfind('/')); Hlsl2Glsl_ParseCallbacks includeCB; includeCB.includeOpenCallback = IncludeOpenCallback; includeCB.includeCloseCallback = NULL; includeCB.data = &includeCtx; int parseOk = Hlsl2Glsl_Parse (parser, sourceStr, version, &includeCB, options); const char* infoLog = Hlsl2Glsl_GetInfoLog( parser ); if (kDumpShaderAST) { // write output FILE* f = fopen ((outputPath+"-ir.txt").c_str(), "wb"); fwrite (infoLog, 1, strlen(infoLog), f); fclose (f); } if (parseOk) { static EAttribSemantic kAttribSemantic[] = { EAttrSemTangent, }; static const char* kAttribString[] = { "TANGENT", }; Hlsl2Glsl_SetUserAttributeNames (parser, kAttribSemantic, kAttribString, 1); int translateOk = Hlsl2Glsl_Translate (parser, entryPoint, version, options); const char* infoLog = Hlsl2Glsl_GetInfoLog( parser ); if (translateOk) { std::string text = GetCompiledShaderText(parser); for (size_t i = 0, n = text.size(); i != n; ++i) { char c = text[i]; if (!isascii(c)) { printf (" contains non-ascii '%c' (0x%02X)\n", c, c); res = false; } } std::string output; ReadStringFromFile (outputPath.c_str(), output); if (text != output) { // write output FILE* f = fopen (outputPath.c_str(), "wb"); fwrite (text.c_str(), 1, text.size(), f); fclose (f); printf (" does not match expected output\n"); res = false; } if (doCheckGLSL && !CheckGLSL (kIsVertexShader[type], version, text)) { res = false; } } else { printf (" translate error: %s\n", infoLog); res = false; } } else { printf (" parse error: %s\n", infoLog); res = false; } Hlsl2Glsl_DestructCompiler (parser); return res; }
static bool TestFile (bool vertex, const std::string& inputPath, const std::string& outputPath, bool usePrecision, bool doCheckGLSL) { std::string input; if (!ReadStringFromFile (inputPath.c_str(), input)) { printf (" failed to read input file\n"); return false; } ShHandle parser = Hlsl2Glsl_ConstructCompiler (vertex ? EShLangVertex : EShLangFragment); const char* sourceStr = input.c_str(); bool res = true; int options = 0; if (kDumpShaderAST) options |= ETranslateOpIntermediate; if (usePrecision) options |= ETranslateOpUsePrecision; int parseOk = Hlsl2Glsl_Parse (parser, sourceStr, options); const char* infoLog = Hlsl2Glsl_GetInfoLog( parser ); if (kDumpShaderAST) { // write output FILE* f = fopen ((outputPath+"-ir.txt").c_str(), "wb"); fwrite (infoLog, 1, strlen(infoLog), f); fclose (f); } if (parseOk) { static EAttribSemantic kAttribSemantic[] = { EAttrSemTangent, }; static const char* kAttribString[] = { "TANGENT", }; Hlsl2Glsl_SetUserAttributeNames (parser, kAttribSemantic, kAttribString, 1); Hlsl2Glsl_UseUserVaryings (parser, true); int translateOk = Hlsl2Glsl_Translate (parser, "main", options); const char* infoLog = Hlsl2Glsl_GetInfoLog( parser ); if (translateOk) { std::string text = Hlsl2Glsl_GetShader (parser); std::string output; ReadStringFromFile (outputPath.c_str(), output); if (text != output) { // write output FILE* f = fopen (outputPath.c_str(), "wb"); fwrite (text.c_str(), 1, text.size(), f); fclose (f); printf (" does not match expected output\n"); res = false; } if (doCheckGLSL && !CheckGLSL (vertex, text.c_str())) { res = false; } } else { printf (" translate error: %s\n", infoLog); res = false; } } else { printf (" parse error: %s\n", infoLog); res = false; } Hlsl2Glsl_DestructCompiler (parser); return res; }