static bool dx9_compile_shader(ShaderCode& out_shader, const ShaderCode& source, ShaderType::type type, FileSystem* fs=NULL, const char* include_dir=NULL) { R_ASSERT(source.type == ShaderCodeType_Text); HRESULT hr = S_OK; ID3DXBuffer* error_buffer = NULL; ID3DXBuffer* shader_buffer = NULL; ID3DXConstantTable* constant_table = NULL; uint32 flags = D3DXSHADER_DEBUG; const char* profile = shader_profile_string(type); static const char dummy_vertex_shader[] = "float4 vertex() : POSITION { return 1; }"; static const char dummy_pixel_shader[] = "float4 pixel() : COLOR { return float4(1,0,1,1); }"; DX9ShaderIncluder includer(fs, include_dir); hr = D3DXCompileShader(source.data(), (UINT)source.size(), NULL, &includer, "main", profile, flags, &shader_buffer, &error_buffer, &constant_table ); if( hr!=S_OK && error_buffer && error_buffer->GetBufferPointer() ) { char* tmp = (char*)error_buffer->GetBufferPointer(); R_ERROR_MESSAGE_BOX(tmp, "Shader compile error"); shader_buffer = NULL; error_buffer = NULL; //create dummy shader if( type == ShaderType::Pixel ) { hr = D3DXCompileShader( dummy_pixel_shader, uint32(strlen(dummy_pixel_shader)), NULL, NULL, "pixel", "ps_2_0", flags, &shader_buffer, &error_buffer, NULL ); validate_d3d_result(hr, true); } else if( type == ShaderType::Vertex ) { hr = D3DXCompileShader( dummy_vertex_shader, uint32(strlen(dummy_vertex_shader)), NULL, NULL, "vertex", "vs_2_0", flags, &shader_buffer, &error_buffer, NULL ); validate_d3d_result(hr, true); } } out_shader.type = ShaderCodeType_Binary; out_shader.clear(); uint32 size = shader_buffer->GetBufferSize(); if( size ) { out_shader.resize(size); memcpy(out_shader.data(), shader_buffer->GetBufferPointer(), size); } if(error_buffer) error_buffer->Release(); if(shader_buffer) shader_buffer->Release(); if(constant_table) constant_table->Release(); return true; }
int C_DECL main(int argc, char* argv[]) { if (argc < 6) { usage(); return 1; } const char* tempdir = argv[4]; //Options |= EOptionHumanReadableSpv; Options |= EOptionSpv; Options |= EOptionLinkProgram; //Options |= EOptionSuppressInfolog; NumWorkItems = 1; Work = new glslang::TWorkItem*[NumWorkItems]; Work[0] = 0; std::string name(argv[2]); if (!SetConfigFile(name)) { Work[0] = new glslang::TWorkItem(name); Worklist.add(Work[0]); } ProcessConfigFile(); glslang::InitializeProcess(); KrafixIncluder includer(name); krafix::Target target; target.system = getSystem(argv[5]); target.es = false; if (strcmp(argv[1], "d3d9") == 0) { target.lang = krafix::HLSL; target.version = 9; CompileAndLinkShaders(target, argv[3], tempdir, includer); } else if (strcmp(argv[1], "d3d11") == 0) { target.lang = krafix::HLSL; target.version = 11; CompileAndLinkShaders(target, argv[3], tempdir, includer); } else if (strcmp(argv[1], "glsl") == 0) { target.lang = krafix::GLSL; if (target.system == krafix::Linux) target.version = 100; else target.version = 330; CompileAndLinkShaders(target, argv[3], tempdir, includer); } else if (strcmp(argv[1], "essl") == 0) { target.lang = krafix::GLSL; target.version = 100; target.es = true; CompileAndLinkShaders(target, argv[3], tempdir, includer); } else if (strcmp(argv[1], "agal") == 0) { target.lang = krafix::AGAL; target.version = 100; target.es = true; CompileAndLinkShaders(target, argv[3], tempdir, includer); } else if (strcmp(argv[1], "metal") == 0) { target.lang = krafix::Metal; target.version = 1; CompileAndLinkShaders(target, argv[3], tempdir, includer); } else if (strcmp(argv[1], "varlist") == 0) { target.lang = krafix::VarList; target.version = 1; CompileAndLinkShaders(target, argv[3], tempdir, includer); } else { std::cout << "Unknown profile " << argv[1] << std::endl; CompileFailed = true; } glslang::FinalizeProcess(); if (CompileFailed) return EFailCompile; if (LinkFailed) return EFailLink; return 0; }
void EffectCompiler::compileHLSL(Profile::eProfile profile, bool vertex, const AbsoluteFilePath& pathToNxfxFolder, const AbsoluteFilePath* pathToFile, const unsigned char* code, int codeLength, const char* entryPoint, std::vector<unsigned char>& result) { #ifdef _WIN32 const char* target; if (vertex) { switch(profile) { case Profile::HLSL_2_0: target = "vs_2_0"; break; case Profile::HLSL_2_a: target = "vs_2_a"; break; case Profile::HLSL_2_b: target = "vs_2_a"; // TODO: is this the best way to handle this? Probably not. break; case Profile::HLSL_3_0: target = "vs_3_0"; break; case Profile::HLSL_4_0: target = "vs_4_0"; break; case Profile::HLSL_4_0_level_9_0: target = "vs_4_0_level_9_0"; break; case Profile::HLSL_4_0_level_9_1: target = "vs_4_0_level_9_1"; break; case Profile::HLSL_4_1: target = "vs_4_1"; break; case Profile::HLSL_5_0: target = "vs_5_0"; break; } } else { switch(profile) { case Profile::HLSL_2_0: target = "ps_2_0"; break; case Profile::HLSL_2_a: target = "ps_2_a"; break; case Profile::HLSL_2_b: target = "ps_2_a"; // TODO: is this the best way to handle this? Probably not. break; case Profile::HLSL_3_0: target = "ps_3_0"; break; case Profile::HLSL_4_0: target = "ps_4_0"; break; case Profile::HLSL_4_0_level_9_0: target = "ps_4_0_level_9_0"; break; case Profile::HLSL_4_0_level_9_1: target = "ps_4_0_level_9_1"; break; case Profile::HLSL_4_1: target = "ps_4_1"; break; case Profile::HLSL_5_0: target = "ps_5_0"; break; } } ID3DBlob* output, *errors; AbsoluteFilePath includerPath = (pathToFile == nullptr ? pathToNxfxFolder : *pathToFile); HLSLIncluder includer(includerPath, pathToFile == nullptr); const char* filePath = (pathToFile == nullptr ? nullptr : pathToFile->GetPath().c_str()); auto r = D3DCompile(code, codeLength, filePath, nullptr, &includer, entryPoint, target, 0, 0, &output, &errors); if (r != S_OK) { throw EffectToolException("Error compiling HLSL shader", (char*)errors->GetBufferPointer()); } result.resize(output->GetBufferSize()); memcpy(result.data(), output->GetBufferPointer(), output->GetBufferSize()); #else throw EffectToolException("HLSL compiling is only available on Windows"); #endif }