CL_ShaderObject CL_ShaderObject::load(CL_GraphicContext &gc, const CL_StringRef &resource_id, CL_ResourceManager *resources) { CL_Resource resource = resources->get_resource(resource_id); CL_String filename = resource.get_element().get_attribute("file"); CL_String type = resource.get_element().get_tag_name(); CL_ShaderType shader_type; if (type == "fragment-shader") shader_type = cl_shadertype_fragment; else if (type == "vertex-shader") shader_type = cl_shadertype_vertex; else throw CL_Exception("CL_ShaderObject: Unknown shader type: " + type); CL_VirtualDirectory directory = resources->get_directory(resource); CL_IODevice file = directory.open_file(filename, CL_File::open_existing, CL_File::access_read, CL_File::share_read); int size = file.get_size(); CL_String8 source(size, 0); file.read(&source[0], size); CL_ShaderObject shader_object(gc, shader_type, CL_StringHelp::local8_to_text(source)); if (resource.get_element().get_attribute("compile", "true") == "true") if(!shader_object.compile()) throw CL_Exception(cl_format("Unable to compiler shader program %1: %2", resource_id, shader_object.get_info_log())); return shader_object; }
bool compile_glsl_to_spv(std::string& shader, program_domain domain, std::vector<u32>& spv) { EShLanguage lang = (domain == glsl_fragment_program) ? EShLangFragment : (domain == glsl_vertex_program)? EShLangVertex : EShLangCompute; glslang::TProgram program; glslang::TShader shader_object(lang); shader_object.setEnvInput(glslang::EShSourceGlsl, lang, glslang::EShClientVulkan, 100); shader_object.setEnvClient(glslang::EShClientVulkan, 100); shader_object.setEnvTarget(glslang::EshTargetSpv, 0x00001000); bool success = false; const char *shader_text = shader.data(); shader_object.setStrings(&shader_text, 1); EShMessages msg = (EShMessages)(EShMsgVulkanRules | EShMsgSpvRules); if (shader_object.parse(&g_default_config, 400, EProfile::ECoreProfile, false, true, msg)) { program.addShader(&shader_object); success = program.link(msg); if (success) { glslang::SpvOptions options; options.disableOptimizer = false; options.optimizeSize = true; glslang::GlslangToSpv(*program.getIntermediate(lang), spv, &options); } } else { LOG_ERROR(RSX, "%s", shader_object.getInfoLog()); LOG_ERROR(RSX, "%s", shader_object.getInfoDebugLog()); } return success; }
bool compile_glsl_to_spv(std::string& shader, glsl::program_domain domain, std::vector<u32>& spv) { EShLanguage lang = (domain == glsl::glsl_fragment_program) ? EShLangFragment : EShLangVertex; glslang::InitializeProcess(); glslang::TProgram program; glslang::TShader shader_object(lang); bool success = false; const char *shader_text = shader.data(); TBuiltInResource rsc; init_default_resources(rsc); shader_object.setStrings(&shader_text, 1); EShMessages msg = (EShMessages)(EShMsgVulkanRules | EShMsgSpvRules); if (shader_object.parse(&rsc, 400, EProfile::ECoreProfile, false, true, msg)) { program.addShader(&shader_object); success = program.link(EShMsgVulkanRules); if (success) { glslang::TIntermediate* bytes = program.getIntermediate(lang); glslang::GlslangToSpv(*bytes, spv); } } else { LOG_ERROR(RSX, "%s", shader_object.getInfoLog()); LOG_ERROR(RSX, "%s", shader_object.getInfoDebugLog()); } glslang::FinalizeProcess(); return success; }