static bool load_program( cg_shader_data_t *cg, unsigned idx, const char *prog, bool path_is_file) { bool ret = true; char *listing_f = NULL; char *listing_v = NULL; unsigned i, argc = 0; const char *argv[2 + GFX_MAX_SHADERS]; argv[argc++] = "-DPARAMETER_UNIFORM"; for (i = 0; i < GFX_MAX_SHADERS; i++) { if (*(cg->cg_alias_define[i])) argv[argc++] = cg->cg_alias_define[i]; } argv[argc] = NULL; if (path_is_file) { cg->prg[idx].fprg = cgCreateProgramFromFile(cg->cgCtx, CG_SOURCE, prog, cg->cgFProf, "main_fragment", argv); SET_LISTING(cg, f); cg->prg[idx].vprg = cgCreateProgramFromFile(cg->cgCtx, CG_SOURCE, prog, cg->cgVProf, "main_vertex", argv); SET_LISTING(cg, v); } else { cg->prg[idx].fprg = cgCreateProgram(cg->cgCtx, CG_SOURCE, prog, cg->cgFProf, "main_fragment", argv); SET_LISTING(cg, f); cg->prg[idx].vprg = cgCreateProgram(cg->cgCtx, CG_SOURCE, prog, cg->cgVProf, "main_vertex", argv); SET_LISTING(cg, v); } if (!cg->prg[idx].fprg || !cg->prg[idx].vprg) { RARCH_ERR("CG error: %s\n", cgGetErrorString(cgGetError())); if (listing_f) RARCH_ERR("Fragment:\n%s\n", listing_f); else if (listing_v) RARCH_ERR("Vertex:\n%s\n", listing_v); ret = false; goto end; } cgGLLoadProgram(cg->prg[idx].fprg); cgGLLoadProgram(cg->prg[idx].vprg); end: free(listing_f); free(listing_v); return ret; }
void Scene::loadShader() { std::string sourcePtr = read("vshader.cg"); auto optimal = cgD3D11GetOptimalOptions(mCgVertexShaderProfile); mVertexShaderId = cgCreateProgram(mCgContext, CG_SOURCE, sourcePtr.c_str(), mCgVertexShaderProfile, "main", optimal); if(mVertexShaderId != nullptr) { optimal = cgD3D11GetOptimalOptions(mCgFragmentShaderProfile); HRESULT res = cgD3D11LoadProgram(mVertexShaderId, NULL); CGerror error; const char *errorString = cgGetLastErrorString(&error); sourcePtr = read("fshader.cg"); mFragmentShaderId = cgCreateProgram(mCgContext, CG_SOURCE, sourcePtr.c_str(), mCgFragmentShaderProfile, "main", optimal); errorString = cgGetLastErrorString(&error); res = cgD3D11LoadProgram(mFragmentShaderId, NULL); } // here the uniform can be set CGparameter location = cgGetNamedParameter(mVertexShaderId, "ambient"); checkForCgError("could not get uniform color location", mCgContext, false); cgSetParameter4fv(location, glm::value_ptr(glm::vec4(1.0,1.0,1.0,1.0))); checkForCgError("could not set uniform color", mCgContext, false); bindShader(mVertexShaderId, mFragmentShaderId); }
static bool d3d9_cg_load_program(void *data, void *fragment_data, void *vertex_data, const char *prog, bool path_is_file) { bool ret = true; const char *list = NULL; char *listing_f = NULL; char *listing_v = NULL; CGprogram *fPrg = (CGprogram*)fragment_data; CGprogram *vPrg = (CGprogram*)vertex_data; CGprofile vertex_profile = cgD3D9GetLatestVertexProfile(); CGprofile fragment_profile = cgD3D9GetLatestPixelProfile(); const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile); const char **vertex_opts = cgD3D9GetOptimalOptions(vertex_profile); cg_renderchain_t *cg_data = (cg_renderchain_t*)data; RARCH_LOG("[D3D Cg]: Vertex profile: %s\n", cgGetProfileString(vertex_profile)); RARCH_LOG("[D3D Cg]: Fragment profile: %s\n", cgGetProfileString(fragment_profile)); if (path_is_file && !string_is_empty(prog)) *fPrg = cgCreateProgramFromFile(cg_data->cgCtx, CG_SOURCE, prog, fragment_profile, "main_fragment", fragment_opts); else *fPrg = cgCreateProgram(cg_data->cgCtx, CG_SOURCE, stock_cg_d3d9_program, fragment_profile, "main_fragment", fragment_opts); list = cgGetLastListing(cg_data->cgCtx); if (list) listing_f = strdup(list); if (path_is_file && !string_is_empty(prog)) *vPrg = cgCreateProgramFromFile(cg_data->cgCtx, CG_SOURCE, prog, vertex_profile, "main_vertex", vertex_opts); else *vPrg = cgCreateProgram(cg_data->cgCtx, CG_SOURCE, stock_cg_d3d9_program, vertex_profile, "main_vertex", vertex_opts); list = cgGetLastListing(cg_data->cgCtx); if (list) listing_v = strdup(list); if (!fPrg || !vPrg) { RARCH_ERR("CG error: %s\n", cgGetErrorString(cgGetError())); if (listing_f) RARCH_ERR("Fragment:\n%s\n", listing_f); else if (listing_v) RARCH_ERR("Vertex:\n%s\n", listing_v); ret = false; goto end; } cgD3D9LoadProgram(*fPrg, true, 0); cgD3D9LoadProgram(*vPrg, true, 0); end: free(listing_f); free(listing_v); return ret; }
static bool renderchain_compile_shaders(cg_renderchain_t *chain, void *fragment_data, void *vertex_data, const std::string &shader) { CGprogram *fPrg = (CGprogram*)fragment_data; CGprogram *vPrg = (CGprogram*)vertex_data; CGprofile vertex_profile = cgD3D9GetLatestVertexProfile(); CGprofile fragment_profile = cgD3D9GetLatestPixelProfile(); const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile); const char **vertex_opts = cgD3D9GetOptimalOptions(vertex_profile); RARCH_LOG("[D3D Cg]: Vertex profile: %s\n", cgGetProfileString(vertex_profile)); RARCH_LOG("[D3D Cg]: Fragment profile: %s\n", cgGetProfileString(fragment_profile)); if (shader.length() > 0) { RARCH_LOG("[D3D Cg]: Compiling shader: %s.\n", shader.c_str()); *fPrg = cgCreateProgramFromFile(chain->cgCtx, CG_SOURCE, shader.c_str(), fragment_profile, "main_fragment", fragment_opts); if (cgGetLastListing(chain->cgCtx)) RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(chain->cgCtx)); *vPrg = cgCreateProgramFromFile(chain->cgCtx, CG_SOURCE, shader.c_str(), vertex_profile, "main_vertex", vertex_opts); if (cgGetLastListing(chain->cgCtx)) RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(chain->cgCtx)); } else { RARCH_LOG("[D3D Cg]: Compiling stock shader.\n"); *fPrg = cgCreateProgram(chain->cgCtx, CG_SOURCE, stock_program, fragment_profile, "main_fragment", fragment_opts); if (cgGetLastListing(chain->cgCtx)) RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(chain->cgCtx)); *vPrg = cgCreateProgram(chain->cgCtx, CG_SOURCE, stock_program, vertex_profile, "main_vertex", vertex_opts); if (cgGetLastListing(chain->cgCtx)) RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(chain->cgCtx)); } if (!fPrg || !vPrg) return false; cgD3D9LoadProgram(*fPrg, true, 0); cgD3D9LoadProgram(*vPrg, true, 0); return true; }
bool RenderChain::compile_shaders(CGprogram &fPrg, CGprogram &vPrg, const std::string &shader) { #ifdef HAVE_CG CGprofile vertex_profile = cgD3D9GetLatestVertexProfile(); CGprofile fragment_profile = cgD3D9GetLatestPixelProfile(); RARCH_LOG("[D3D Cg]: Vertex profile: %s\n", cgGetProfileString(vertex_profile)); RARCH_LOG("[D3D Cg]: Fragment profile: %s\n", cgGetProfileString(fragment_profile)); const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile); const char **vertex_opts = cgD3D9GetOptimalOptions(vertex_profile); if (shader.length() > 0) { RARCH_LOG("[D3D Cg]: Compiling shader: %s.\n", shader.c_str()); fPrg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, shader.c_str(), fragment_profile, "main_fragment", fragment_opts); if (cgGetLastListing(cgCtx)) RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(cgCtx)); vPrg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, shader.c_str(), vertex_profile, "main_vertex", vertex_opts); if (cgGetLastListing(cgCtx)) RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(cgCtx)); } else { RARCH_LOG("[D3D Cg]: Compiling stock shader.\n"); fPrg = cgCreateProgram(cgCtx, CG_SOURCE, stock_program, fragment_profile, "main_fragment", fragment_opts); if (cgGetLastListing(cgCtx)) RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(cgCtx)); vPrg = cgCreateProgram(cgCtx, CG_SOURCE, stock_program, vertex_profile, "main_vertex", vertex_opts); if (cgGetLastListing(cgCtx)) RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(cgCtx)); } if (!fPrg || !vPrg) return false; cgD3D9LoadProgram(fPrg, true, 0); cgD3D9LoadProgram(vPrg, true, 0); #endif return true; }
//----------------------------------------------------------------------- void CgProgram::loadFromSource(void) { // Create Cg Program selectProfile(); if (mSelectedCgProfile == CG_PROFILE_UNKNOWN) { LogManager::getSingleton().logMessage( "Attempted to load Cg program '" + mName + "', but no suported " "profile was found. "); return; } buildArgs(); // deal with includes String sourceToUse = resolveCgIncludes(mSource, this, mFilename); mCgProgram = cgCreateProgram(mCgContext, CG_SOURCE, sourceToUse.c_str(), mSelectedCgProfile, mEntryPoint.c_str(), const_cast<const char**>(mCgArguments)); // Test //LogManager::getSingleton().logMessage(cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM)); // Check for errors checkForCgError("CgProgram::loadFromSource", "Unable to compile Cg program " + mName + ": ", mCgContext); }
IOGLBaseShader::IOGLBaseShader(CRefPtr<COGLDevice> pDevice, const Graphic::ShaderType uType, const Graphic::ShaderVersion uVersion, CGenum uSourceType, CGprofile uProfile, const CString& strSource, const CString& strEntryPoint) : m_uVersion(uVersion), m_uType(uType), m_uProgram(0), m_bBinded(false), Manage::IManagedObject<COGLDevice, IOGLBaseShader>(pDevice) { if(!cgIsProfileSupported(uProfile)){ throw Exception::CInvalidArgumentException(L"uProfile", String::FromANSI(reinterpret_cast<const int8*>(cgGetProfileString(uProfile))), L"Unsupported shader profile.", CR_INFO()); } auto szSource = String::ToANSI(strSource); auto szEntryPoint = String::ToANSI(strEntryPoint); this->m_uProgram = cgCreateProgram(this->GetParent()->GetCGC().Get(), uSourceType, reinterpret_cast<const char*>(szSource.GetPointer()), uProfile, reinterpret_cast<const char*>(szEntryPoint.GetPointer()), 0); if(!cgIsProgram(this->m_uProgram)){ CR_THROW(L"Failed to create shader program."); } cgCompileProgram(this->m_uProgram); if(!cgIsProgramCompiled(this->m_uProgram)){ CR_THROW(L"Failed to compile program."); } cgGLLoadProgram(this->m_uProgram); }
bool CgGLShader::initialize(const ResourcePtr& resource, const ShaderDesc& desc) { CGprofile profile; mDesc = desc; switch (desc.type) { case ukn::ST_FragmentShader: profile = cgGLGetLatestProfile(CG_GL_FRAGMENT); break; case ukn::ST_VertexShader: profile = cgGLGetLatestProfile(CG_GL_VERTEX); break; case ukn::ST_GeometryShader: profile = cgGLGetLatestProfile(CG_GL_GEOMETRY); break; } StreamPtr stream = resource->readIntoMemory(); if(!stream) return false; MemoryStream* memStream = ((MemoryStream*)stream.get()); std::string content(memStream->data(), memStream->data() + memStream->size()); mProgram = cgCreateProgram(mContext, CG_SOURCE, content.c_str(), profile, desc.entry.c_str(), cgGLGetOptimalOptions(profile)); if(_check_error(mContext)) { cgGLLoadProgram(mProgram); mProfile = profile; return _check_error(mContext); } return false;; }
bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram) { // Reset GL error before compiling shaders. Yeah, we need to investigate the causes of these. GLenum err = GL_REPORT_ERROR(); if (err != GL_NO_ERROR) { ERROR_LOG(VIDEO, "glError %08x before VS!", err); } #if defined HAVE_CG && HAVE_CG char stropt[64]; sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions); const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", opts); if (!cgIsProgram(tempprog)) { if (s_displayCompileAlert) { PanicAlert("Failed to create vertex shader"); s_displayCompileAlert = false; } cgDestroyProgram(tempprog); ERROR_LOG(VIDEO, "Failed to load vs %s:", cgGetLastListing(g_cgcontext)); ERROR_LOG(VIDEO, "%s", pstrprogram); return false; } if (cgGetError() != CG_NO_ERROR) { WARN_LOG(VIDEO, "Failed to load vs %s:", cgGetLastListing(g_cgcontext)); WARN_LOG(VIDEO, "%s", pstrprogram); } // This looks evil - we modify the program through the const char * we got from cgGetProgramString! // It SHOULD not have any nasty side effects though - but you never know... char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); char *plocal = strstr(pcompiledprog, "program.local"); while (plocal != NULL) { const char* penv = " program.env"; memcpy(plocal, penv, 13); plocal = strstr(plocal + 13, "program.local"); } glGenProgramsARB(1, &vs.glprogid); SetCurrentShader(vs.glprogid); glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); err = GL_REPORT_ERROR(); if (err != GL_NO_ERROR) { ERROR_LOG(VIDEO, "%s", pstrprogram); ERROR_LOG(VIDEO, "%s", pcompiledprog); } cgDestroyProgram(tempprog); #endif #if defined(_DEBUG) || defined(DEBUGFAST) vs.strprog = pstrprogram; #endif return true; }
static bool load_program(unsigned index, const char *prog, bool path_is_file) { bool ret = true; char *listing_f = NULL; char *listing_v = NULL; if (path_is_file) { prg[index].fprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, prog, cgFProf, "main_fragment", cg_arguments); SET_LISTING(f); prg[index].vprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, prog, cgVProf, "main_vertex", cg_arguments); SET_LISTING(v); } else { prg[index].fprg = cgCreateProgram(cgCtx, CG_SOURCE, prog, cgFProf, "main_fragment", cg_arguments); SET_LISTING(f); prg[index].vprg = cgCreateProgram(cgCtx, CG_SOURCE, prog, cgVProf, "main_vertex", cg_arguments); SET_LISTING(v); } if (!prg[index].fprg || !prg[index].vprg) { RARCH_ERR("CG error: %s\n", cgGetErrorString(cgGetError())); if (listing_f) RARCH_ERR("Fragment:\n%s\n", listing_f); else if (listing_v) RARCH_ERR("Vertex:\n%s\n", listing_v); ret = false; goto end; } cgGLLoadProgram(prg[index].fprg); cgGLLoadProgram(prg[index].vprg); end: free(listing_f); free(listing_v); return ret; }
bool Shader::compileSourceCode (CGcontext context, const QString& code, const QString& entryPoint) { d->profile = cgGLGetLatestProfile(d->profileClass); qDebug("profile: %s", cgGetProfileString(d->profile)); cgGLSetOptimalOptions(d->profile); d->program = cgCreateProgram(context, CG_SOURCE, code.toLocal8Bit(), d->profile, entryPoint.toLocal8Bit(), NULL); return true; }
CGprogram CCGShaderSystem::CreateProgram(lpcastr lpszShaderCode, CGprofile Profile, lpcastr lpszEntryPoint, lpcastr lpszShaderName) { XST_LOG_ERR( lpszShaderCode ); CGprogram Program = cgCreateProgram( m_CGContext, CG_SOURCE, lpszShaderCode, Profile, lpszEntryPoint, xst_null ); if( XST_FAILED( this->CheckForErrors( "Program creation", lpszShaderName ) ) ) { if( Program ) { cgDestroyProgram( Program ); } return xst_null; } return Program; }
static __forceinline void LOAD_VS(int Index, ZZshProgram prog) { assert(mapShaderResources.find(Index) != mapShaderResources.end()); header = mapShaderResources[Index]; assert((header) != NULL && (header)->index == (Index)); prog = cgCreateProgram(g_cgcontext, CG_OBJECT, (char*)(s_lpShaderResources + (header)->offset), cgvProf, NULL, NULL); if (!cgIsProgram(prog)) { ZZLog::Error_Log("Failed to load vs %d: \n%s", Index, cgGetLastListing(g_cgcontext)); return false; } cgGLLoadProgram(prog); if (cgGetError() != CG_NO_ERROR) ZZLog::Error_Log("Failed to load program %d.", Index); SetupVertexProgramParameters(prog, !!(Index&SH_CONTEXT1)); }
CGprogram ShaderPair::loadShader(const QString& fileName, CGprofile profile) { QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) qFatal("Could not open file %s", fileName.toAscii().data()); // Load and null terminate the program source char* source = new char[file.size() + 1]; file.read(source, file.size()); source[file.size()] = 0; CGprogram program = cgCreateProgram(m_context, CG_SOURCE, source, profile, NULL, NULL); if (program) cgGLLoadProgram(program); else qFatal("Error loading Cg program %s", fileName.toAscii().data()); delete[] source; return program; }
bool CgDxShader::initialize(D3D11GraphicDevice* device, const ResourcePtr& resource, const ShaderDesc& desc) { mDesc = desc; StreamPtr stream = resource->readIntoMemory(); if(!stream) return false; MemoryStream* memStream = ((MemoryStream*)stream.get()); std::string content(memStream->data(), memStream->data() + memStream->size()); CGprofile profile = _d3d_feature_level_to_cgprofile(device->getDeviceFeatureLevel(), desc.type); mProgram = cgCreateProgram(mContext, CG_SOURCE, content.c_str(), profile, desc.entry.c_str(), cgD3D11GetOptimalOptions(profile)); if(_check_error(mContext) && D3D11Debug::CHECK_RESULT( cgD3D11LoadProgram(mProgram, 0))) { return true; } return false; }
static __forceinline void LOAD_VS(int Index, FRAGMENTSHADER fragment) { bLoadSuccess = true; assert(mapShaderResources.find(Index) != mapShaderResources.end()); header = mapShaderResources[Index]; fragment.prog = cgCreateProgram(g_cgcontext, CG_OBJECT, (char*)(s_lpShaderResources + (header)->offset), cgfProf, NULL, NULL); if (!cgIsProgram(fragment.prog)) { ZZLog::Error_Log("Failed to load ps %d: \n%s", Index, cgGetLastListing(g_cgcontext)); return false; } cgGLLoadProgram(fragment.prog); if (cgGetError() != CG_NO_ERROR) { ZZLog::Error_Log("failed to load program %d.", Index); bLoadSuccess = false; } SetupFragmentProgramParameters(&fragment, !!(Index&SH_CONTEXT1), 0); }
bool GLCgShader::CreateCgProgram() { DestroyCgProgram(); m_cgProgam = cgCreateProgram( m_cgContext, CG_SOURCE, m_shaderCode.c_str(), m_cgProfile, m_entry.empty() ? NULL : m_entry.c_str(), NULL); if (CheckForError("Shader::LoadShader creating program from file", m_shaderName)) return false; // compile shader cgGLLoadProgram(m_cgProgam); if (CheckForError("GS_SHADER::CompileShader loading the program", m_shaderName)) return false; FillParameters(CG_GLOBAL); FillParameters(CG_PROGRAM); return true; }
Shader* RendererGL::CreatePixelShaderFromString( const char* PixelCode, const char* PixelMain /*= "PSMain"*/, ShaderVersion ePVersion /*= ESV_PS1_1*/ ) { CGprogram CgPixelProgram = cgCreateProgram ( m_CgContext, CG_SOURCE, PixelCode, m_CgFragmentProfile, PixelMain, NULL ); /* No extra compiler options */ checkForCgError("creating pixel program from string"); if (!CgPixelProgram) return NULL; cgGLLoadProgram(CgPixelProgram); checkForCgError("loading pixel program"); Shader *shader = KGE_NEW(ShaderGL)(CgPixelProgram, 0, NULL, NULL); return shader; }
static sBool sCompileCg(sCompileResult &result, sInt stype, sInt dtype, sInt flags, const sChar8 *src, sInt len, const sChar8 *name) { #if sCOMP_CG_ENABLE if(result.Cg.Program) cgDestroyProgram(result.Cg.Program); sChar8 *src8 = new sChar8[len]; sCopyString(src8,src,len); CGprofile prof = cgGetProfile(GetProfile(dtype)); CGprogram program = cgCreateProgram(CGC,CG_SOURCE,src8,prof,name,0); if(GetCgError(result.Errors)) goto error; cgCompileProgram(program); if(GetCgError(result.Errors)) goto error; const sChar8 *out8 = cgGetProgramString(program,CG_COMPILED_PROGRAM); if(GetCgError(result.Errors)) goto error; sInt size = 0; while(out8[size]) size++; sAddShaderBlob(result.ShaderBlobs,dtype,size,(const sU8*)out8); result.Valid = sTRUE; sDeleteArray(src8); return sTRUE; error: result.Valid = sFALSE; sDeleteArray(src8); return sFALSE; #else sLogF(L"asc",L"sCOMP_CG_ENABLE == 0 no cg compiler available\n"); return sFALSE; #endif // sCOMP_CG_ENABLE }
// CreateVertexShaderFromString Shader* RendererGL::CreateVertexShaderFromString(const char* VertexCode, const char* VertexMain, ShaderVersion eVVersion) { CGprogram CgVertexProgram = cgCreateProgram ( m_CgContext, /* Cg runtime context */ CG_SOURCE, /* Program in human-readable form */ VertexCode, /* Vertex shader source code */ m_CgVertexProfile, /* Profile: OpenGL ARB vertex program */ VertexMain, /* Entry function name */ NULL ); /* No extra compiler options */ checkForCgError("creating vertex program from string"); if (!CgVertexProgram) return NULL; cgGLLoadProgram(CgVertexProgram); checkForCgError("loading vertex program"); Shader *shader = KGE_NEW(ShaderGL)(CgVertexProgram, 0, NULL, NULL); return shader; } // CreateVertexShaderFromString
//----------------------------------------------------------------------- void CgProgram::compileMicrocode(void) { // Create Cg Program /// Program handle CGprogram cgProgram; if (mSelectedCgProfile == CG_PROFILE_UNKNOWN) { LogManager::getSingleton().logMessage( "Attempted to load Cg program '" + mName + "', but no supported " "profile was found. "); return; } buildArgs(); // deal with includes String sourceToUse = resolveCgIncludes(mSource, this, mFilename); cgProgram = cgCreateProgram(mCgContext, CG_SOURCE, sourceToUse.c_str(), mSelectedCgProfile, mEntryPoint.c_str(), const_cast<const char**>(mCgArguments)); // Test //LogManager::getSingleton().logMessage(cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM)); // Check for errors checkForCgError("CgProgram::compileMicrocode", "Unable to compile Cg program " + mName + ": ", mCgContext); CGerror error = cgGetError(); if (error == CG_NO_ERROR) { // get program string (result of cg compile) mProgramString = cgGetProgramString(cgProgram, CG_COMPILED_PROGRAM); checkForCgError("CgProgram::compileMicrocode", "Unable to retrieve program code for Cg program " + mName + ": ", mCgContext); // get params mParametersMap.clear(); mParametersMapSizeAsBuffer = 0; mSamplerRegisterMap.clear(); recurseParams(cgGetFirstParameter(cgProgram, CG_PROGRAM)); recurseParams(cgGetFirstParameter(cgProgram, CG_GLOBAL)); if (mDelegate) { // Delegating to HLSL or GLSL, need to clean up Cg's output fixHighLevelOutput(mProgramString); if (mSelectedCgProfile == CG_PROFILE_GLSLG) { // need to determine input and output operations mInputOp = cgGetProgramInput(cgProgram); mOutputOp = cgGetProgramOutput(cgProgram); } } // Unload Cg Program - we don't need it anymore cgDestroyProgram(cgProgram); //checkForCgError("CgProgram::unloadImpl", // "Error while unloading Cg program " + mName + ": ", // mCgContext); cgProgram = 0; if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache()) { addMicrocodeToCache(); } } }
void COpenGLCgMaterialRenderer::init(s32& materialType, const c8* vertexProgram, const c8* vertexEntry, E_VERTEX_SHADER_TYPE vertexProfile, const c8* fragmentProgram, const c8* fragmentEntry, E_PIXEL_SHADER_TYPE fragmentProfile, const c8* geometryProgram, const c8* geometryEntry, E_GEOMETRY_SHADER_TYPE geometryProfile, scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, u32 vertices) { bool Status = true; CGerror Error = CG_NO_ERROR; materialType = -1; // TODO: add profile selection if (vertexProgram) { VertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); if (VertexProfile) VertexProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, vertexProgram, VertexProfile, vertexEntry, 0); if (!VertexProgram) { Error = cgGetError(); os::Printer::log("Cg vertex program failed to compile:", ELL_ERROR); os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); Status = false; } else cgGLLoadProgram(VertexProgram); } if (fragmentProgram) { FragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); if (FragmentProfile) FragmentProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, fragmentProgram, FragmentProfile, fragmentEntry, 0); if (!FragmentProgram) { Error = cgGetError(); os::Printer::log("Cg fragment program failed to compile:", ELL_ERROR); os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); Status = false; } else cgGLLoadProgram(FragmentProgram); } if (geometryProgram) { GeometryProfile = cgGLGetLatestProfile(CG_GL_GEOMETRY); if (GeometryProfile) GeometryProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, geometryProgram, GeometryProfile, geometryEntry, 0); if (!GeometryProgram) { Error = cgGetError(); os::Printer::log("Cg geometry program failed to compile:", ELL_ERROR); os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); Status = false; } else cgGLLoadProgram(GeometryProgram); } getUniformList(); // create OpenGL specifics sampler uniforms. for (unsigned int i = 0; i < UniformInfo.size(); ++i) { if (UniformInfo[i]->getType() == CG_SAMPLER2D) { bool IsGlobal = true; if (UniformInfo[i]->getSpace() == CG_PROGRAM) IsGlobal = false; CCgUniform* Uniform = new COpenGLCgUniformSampler2D(UniformInfo[i]->getParameter(), IsGlobal); delete UniformInfo[i]; UniformInfo[i] = Uniform; } } if (Status) materialType = Driver->addMaterialRenderer(this); }
static bool gl_cg_compile_program( void *data, unsigned idx, void *program_data, struct shader_program_info *program_info) { const char *list = NULL; const char *argv[2 + GFX_MAX_SHADERS]; bool ret = true; char *listing_f = NULL; char *listing_v = NULL; unsigned i, argc = 0; struct shader_program_cg *program = (struct shader_program_cg*)program_data; cg_shader_data_t *cg = (cg_shader_data_t*)data; if (!program) program = &cg->prg[idx]; argv[argc++] = "-DPARAMETER_UNIFORM"; for (i = 0; i < GFX_MAX_SHADERS; i++) { if (*(cg->alias_define[i])) argv[argc++] = cg->alias_define[i]; } argv[argc] = NULL; if (program_info->is_file) program->fprg = cgCreateProgramFromFile( cg->cgCtx, CG_SOURCE, program_info->combined, cg->cgFProf, "main_fragment", argv); else program->fprg = cgCreateProgram(cg->cgCtx, CG_SOURCE, program_info->combined, cg->cgFProf, "main_fragment", argv); list = cgGetLastListing(cg->cgCtx); if (list) listing_f = strdup(list); list = NULL; if (program_info->is_file) program->vprg = cgCreateProgramFromFile( cg->cgCtx, CG_SOURCE, program_info->combined, cg->cgVProf, "main_vertex", argv); else program->vprg = cgCreateProgram(cg->cgCtx, CG_SOURCE, program_info->combined, cg->cgVProf, "main_vertex", argv); list = cgGetLastListing(cg->cgCtx); if (list) listing_v = strdup(list); if (!program->fprg || !program->vprg) { RARCH_ERR("CG error: %s\n", cgGetErrorString(cgGetError())); if (listing_f) RARCH_ERR("Fragment:\n%s\n", listing_f); else if (listing_v) RARCH_ERR("Vertex:\n%s\n", listing_v); ret = false; goto end; } cgGLLoadProgram(program->fprg); cgGLLoadProgram(program->vprg); end: free(listing_f); free(listing_v); return ret; }
bool CGLCG::LoadShader(const TCHAR *shaderFile) { CCGShader cgShader; TCHAR shaderPath[MAX_PATH]; TCHAR tempPath[MAX_PATH]; CGprofile vertexProfile, fragmentProfile; GLenum error; if(!fboFunctionsLoaded) { MessageBox(NULL, TEXT("Your OpenGL graphics driver does not support framebuffer objects.\nYou will not be able to use CG shaders in OpenGL mode."), TEXT("CG Error"), MB_OK|MB_ICONEXCLAMATION); return false; } vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); cgGLDisableProfile(vertexProfile); cgGLDisableProfile(fragmentProfile); ClearPasses(); if (shaderFile == NULL || *shaderFile==TEXT('\0')) return true; lstrcpy(shaderPath, shaderFile); ReduceToPath(shaderPath); SetCurrentDirectory(shaderPath); if(!cgShader.LoadShader(_tToChar(shaderFile))) return false; cgGLSetOptimalOptions(vertexProfile); cgGLSetOptimalOptions(fragmentProfile); /* insert dummy pass that will contain the original texture */ shaderPasses.push_back(shaderPass()); for(CCGShader::passVector::iterator it=cgShader.shaderPasses.begin(); it!=cgShader.shaderPasses.end();it++) { shaderPass pass; pass.scaleParams = it->scaleParams; /* if this is the last pass (the only one that can have CG_SCALE_NONE) and no filter has been set use the GUI setting */ if(pass.scaleParams.scaleTypeX==CG_SCALE_NONE && !it->filterSet) { pass.linearFilter = GUI.BilinearFilter; } else { pass.linearFilter = it->linearFilter; } pass.frameCounterMod = it->frameCounterMod; pass.floatFbo = it->floatFbo; // paths in the meta file can be relative _tfullpath(tempPath,_tFromChar(it->cgShaderFile),MAX_PATH); char *fileContents = ReadShaderFileContents(tempPath); if(!fileContents) return false; // individual shader might include files, these should be relative to shader ReduceToPath(tempPath); SetCurrentDirectory(tempPath); pass.cgVertexProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents, vertexProfile, "main_vertex", NULL); checkForCgError("Compiling vertex program"); pass.cgFragmentProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents, fragmentProfile, "main_fragment", NULL); checkForCgError("Compiling fragment program"); // set path back for next pass SetCurrentDirectory(shaderPath); delete [] fileContents; if(!pass.cgVertexProgram || !pass.cgFragmentProgram) { return false; } cgGLLoadProgram(pass.cgVertexProgram); cgGLLoadProgram(pass.cgFragmentProgram); /* generate framebuffer and texture for this pass and apply default texture settings */ glGenFramebuffers(1,&pass.fbo); glGenTextures(1,&pass.tex); glBindTexture(GL_TEXTURE_2D,pass.tex); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); shaderPasses.push_back(pass); } for(std::vector<CCGShader::lookupTexture>::iterator it=cgShader.lookupTextures.begin();it!=cgShader.lookupTextures.end();it++) { lookupTexture tex; strcpy(tex.id,it->id); /* generate texture for the lut and apply specified filter setting */ glGenTextures(1,&tex.tex); glBindTexture(GL_TEXTURE_2D,tex.tex); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, it->linearfilter?GL_LINEAR:GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, it->linearfilter?GL_LINEAR:GL_NEAREST); _tfullpath(tempPath,_tFromChar(it->texturePath),MAX_PATH); // simple file extension png/tga decision int strLen = strlen(it->texturePath); if(strLen>4) { if(!strcasecmp(&it->texturePath[strLen-4],".png")) { int width, height; bool hasAlpha; GLubyte *texData; if(loadPngImage(tempPath,width,height,hasAlpha,&texData)) { glPixelStorei(GL_UNPACK_ROW_LENGTH, width); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, hasAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, texData); free(texData); } } else if(!strcasecmp(&it->texturePath[strLen-4],".tga")) { STGA stga; if(loadTGA(tempPath,stga)) { glPixelStorei(GL_UNPACK_ROW_LENGTH, stga.width); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, stga.width, stga.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, stga.data); } } } lookupTextures.push_back(tex); } /* enable texture unit 1 for the lookup textures */ glClientActiveTexture(GL_TEXTURE1); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2,GL_FLOAT,0,lut_coords); glClientActiveTexture(GL_TEXTURE0); /* generate textures and set default values for the pref-filled PREV deque. */ for(int i=0;i<prevPasses.size();i++) { glGenTextures(1,&prevPasses[i].tex); glBindTexture(GL_TEXTURE_2D,prevPasses[i].tex); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,512,512,0,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,NULL); glBindTexture(GL_TEXTURE_2D,0); prevPasses[i].textureSize.x = prevPasses[i].textureSize.y = prevPasses[i].textureSize.x = prevPasses[i].textureSize.y = 0; memset(prevPasses[i].texCoords,0,sizeof(prevPasses[i].texCoords)); } shaderLoaded = true; return true; }
//--------------------------------------------------------------------------------- // init // this function load and compile a vertex/fragment program on the specified context // if the source file is not found, it assigns a default GREEN color shader // if the compile failed, it assigns a default RED color shader //--------------------------------------------------------------------------------- bool FFxProgram::init(CGcontext aContext) { CGenum fileType; // remove existing program (in case a program is already loaded) if (mProgram) { cgDestroyProgram(mProgram); mProgram = 0; } fileType = CG_SOURCE; #ifdef WIN32 HRESULT hr; if (GDD->GetClassID() == ClassIDZDisplayDeviceDX9) { const char** profileOpts; profileOpts = cgD3D9GetOptimalOptions(mProfile); const char *nOpts[16]; nOpts[0] = COMPILE_ARGS[0]; int idx =1; while ( (idx<15) && profileOpts[idx-1]) { nOpts[idx] = profileOpts[idx-1]; idx++; } nOpts[idx] = 0; const char *szDXprofile = NULL; if (mProfile == CG_PROFILE_VS_2_0) { szDXprofile = D3DXGetVertexShaderProfile(GDD->GetD3D9Device()); } else { szDXprofile = D3DXGetPixelShaderProfile(GDD->GetD3D9Device()); } /* //LPD3DXBUFFER mDXShader; D3DXCompileShader( mSourceBuffer, strlen(mSourceBuffer), NULL, NULL, mEntry.c_str(), szDXprofile, 0, &mDXShader, NULL, NULL ); */ mProgram = cgCreateProgram(aContext, fileType, mSourceBuffer, mProfile, mEntry.c_str(), nOpts); hr = cgD3D9LoadProgram(mProgram, true, 0); } else #endif { // opengl //mProgram = cgCreateProgram(aContext, fileType, mSourceBuffer, mProfile, mEntry.c_str(), COMPILE_ARGS); mProfile = (mProfileDomain == CG_VERTEX_DOMAIN) ?cgGLGetLatestProfile(CG_GL_VERTEX):cgGLGetLatestProfile(CG_GL_FRAGMENT ); assert(cgGLIsProfileSupported(mProfile)); mProgram = cgCreateProgramFromFile(aContext, fileType, mFileName, mProfile, mEntry.c_str(), COMPILE_ARGS); if (mProgram == NULL) { CGerror error; const char* errTxt = cgGetLastErrorString(&error); LOG ("ERROR %x: can't compile %s : %s\n", error, mFileName.c_str(), errTxt); useDefaultProgram(aContext); assert(false); return false; } cgGLLoadProgram(mProgram); checkForCgError("loadprog"); } if (mProgram == 0) { CGerror error = cgGetError(); LOG ("ERROR %x: can't load or compile %s : %s\n", error, mFileName.c_str(), cgGetLastErrorString(&error)); useDefaultProgram(aContext); assert(false); return false; } return true; }
static bool d3d9_cg_load_program(void *data, struct shader_pass *pass, const char *prog, bool path_is_file) { const char *list = NULL; char *listing_f = NULL; char *listing_v = NULL; CGprofile vertex_profile = cgD3D9GetLatestVertexProfile(); CGprofile fragment_profile = cgD3D9GetLatestPixelProfile(); const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile); const char **vertex_opts = cgD3D9GetOptimalOptions(vertex_profile); cg_renderchain_t *chain = (cg_renderchain_t*)data; CGcontext cgCtx = chain->cgCtx; if ( fragment_profile == CG_PROFILE_UNKNOWN || vertex_profile == CG_PROFILE_UNKNOWN) { RARCH_ERR("Invalid profile type\n"); goto error; } RARCH_LOG("[D3D9 Cg]: Vertex profile: %s\n", cgGetProfileString(vertex_profile)); RARCH_LOG("[D3D9 Cg]: Fragment profile: %s\n", cgGetProfileString(fragment_profile)); if (path_is_file && !string_is_empty(prog)) pass->fprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, prog, fragment_profile, "main_fragment", fragment_opts); else pass->fprg = cgCreateProgram(cgCtx, CG_SOURCE, stock_cg_d3d9_program, fragment_profile, "main_fragment", fragment_opts); list = cgGetLastListing(cgCtx); if (list) listing_f = strdup(list); if (path_is_file && !string_is_empty(prog)) pass->vprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, prog, vertex_profile, "main_vertex", vertex_opts); else pass->vprg = cgCreateProgram(cgCtx, CG_SOURCE, stock_cg_d3d9_program, vertex_profile, "main_vertex", vertex_opts); list = cgGetLastListing(cgCtx); if (list) listing_v = strdup(list); if (!pass->fprg || !pass->vprg) goto error; cgD3D9LoadProgram(pass->fprg, true, 0); cgD3D9LoadProgram(pass->vprg, true, 0); free(listing_f); free(listing_v); return true; error: RARCH_ERR("CG error: %s\n", cgGetErrorString(cgGetError())); if (listing_f) RARCH_ERR("Fragment:\n%s\n", listing_f); else if (listing_v) RARCH_ERR("Vertex:\n%s\n", listing_v); free(listing_f); free(listing_v); return false; }
bool csShaderGLCGCommon::DefaultLoadProgram (iShaderProgramCG* cgResolve, const char* programStr, ProgramType _type, const ProfileLimitsPair& customLimitsPair, uint flags) { if (!programStr || !*programStr) return false; const ProfileLimits& customLimits = (_type == progVP) ? customLimitsPair.vp : customLimitsPair.fp; CGGLenum type = (_type == progVP) ? CG_GL_VERTEX : CG_GL_FRAGMENT; size_t i; csString augmentedProgramStr = GetAugmentedProgram (programStr, (flags & loadFlagUnusedV2FForInit) != 0); programStr = augmentedProgramStr; CGprofile profile = customLimits.profile; CS::PluginCommon::ShaderProgramPluginGL::HardwareVendor vendor = customLimits.vendor; if (shaderPlug->doVerbose || shaderPlug->doVerbosePrecache) { shaderPlug->Report (CS_REPORTER_SEVERITY_NOTIFY, "Cg %s program %s: using profile %s[%d]", GetProgramType(), CS::Quote::Single (description.GetData ()), cgGetProfileString (profile), profile); } ArgumentArray args; shaderPlug->GetProfileCompilerArgs (GetProgramType(), profile, customLimitsPair, vendor, (flags & loadIgnoreConfigProgramOpts) ? csGLShader_CG::argsNoConfig : csGLShader_CG::argsAll, args); for (i = 0; i < compilerArgs.GetSize(); i++) args.Push (compilerArgs[i]); programPositionInvariant = false; for (i = 0; i < args.GetSize(); ) { if (strcmp (args[i], "-posinv") == 0) { if (profile >= CG_PROFILE_GPU_VP) { /* Work around Cg 2.0 and above (including 3.0) bug: it emits "OPTION ARB_position_invariant;" AND computes result.position in the VP - doing both is verboten. Affected are the GP4VP and higher profiles. Remedy: remove -posinv argument */ args.DeleteIndex (i); continue; } programPositionInvariant = true; } i++; } customLimits.ToCgOptions (args); args.Push (0); if (program) { cgDestroyProgram (program); } shaderPlug->SetCompiledSource (programStr); shaderPlug->SetIgnoreErrors (true); program = cgCreateProgram (shaderPlug->context, CG_SOURCE, programStr, profile, !entrypoint.IsEmpty() ? entrypoint : "main", args.GetArray()); shaderPlug->SetIgnoreErrors (false); if (!(flags & loadIgnoreErrors)) shaderPlug->PrintAnyListing(); if (!program) { shaderPlug->SetCompiledSource (0); /*if (shaderPlug->debugDump) { EnsureDumpFile(); WriteAdditionalDumpInfo ("Failed program source", programStr); }*/ return false; } programProfile = cgGetProgramProfile (program); GetParamsFromVmapConstants(); if (flags & loadApplyVmap) GetParamsFromVmap(); if (flags & loadIgnoreErrors) shaderPlug->SetIgnoreErrors (true); cgCompileProgram (program); if (flags & loadIgnoreErrors) shaderPlug->SetIgnoreErrors (false); else shaderPlug->PrintAnyListing(); if (flags & loadApplyVmap) GetPostCompileParamProps (); if (flags & loadLoadToGL) { cgGetError(); // Clear error cgGLLoadProgram (program); if (!(flags & loadIgnoreErrors)) shaderPlug->PrintAnyListing(); if ((cgGetError() != CG_NO_ERROR) || !cgGLIsProgramLoaded (program)) { if (shaderPlug->debugDump) DoDebugDump(); if (shaderPlug->doVerbose && (((type == CG_GL_VERTEX) && (profile >= CG_PROFILE_ARBVP1)) || ((type == CG_GL_FRAGMENT) && (profile >= CG_PROFILE_ARBFP1)))) { csString err = (char*)glGetString (GL_PROGRAM_ERROR_STRING_ARB); if (!err.IsEmpty()) shaderPlug->Report (CS_REPORTER_SEVERITY_WARNING, "OpenGL error string: %s", err.GetData()); } shaderPlug->SetCompiledSource (0); return false; } } if (shaderPlug->debugDump) DoDebugDump(); shaderPlug->SetCompiledSource (0); bool result = true; if (programType == progFP) { int numVaryings = 0; CGparameter param = cgGetFirstLeafParameter (program, CG_PROGRAM); while (param) { if (cgIsParameterUsed (param, program) && cgIsParameterReferenced (param)) { const CGenum var = cgGetParameterVariability (param); if (var == CG_VARYING) numVaryings++; } param = cgGetNextLeafParameter (param); } /* WORKAROUND: Even NVs G80 doesn't support passing more than 16 attribs into an FP, yet Cg happily generates code that uses more (and GL falls back to SW). So manually check the number of varying inputs and reject more than 16. @@@ This should be at least configurable */ const int maxNumVaryings = 16; if (numVaryings > maxNumVaryings) { if (shaderPlug->doVerbose || shaderPlug->doVerbosePrecache) { shaderPlug->Report (CS_REPORTER_SEVERITY_NOTIFY, "Discarding compiled program for having too much varyings " "(%d, limit is %d)", numVaryings, maxNumVaryings); } cgDestroyProgram (program); program = 0; result = false; } } if (!result && !debugFN.IsEmpty()) { csRef<iVFS> vfs = csQueryRegistry<iVFS> (objectReg); vfs->DeleteFile (debugFN); } return result; }
iShaderProgram::CacheLoadResult csShaderGLCGCommon::LoadFromCache ( iHierarchicalCache* cache, iBase* previous, iDocumentNode* node, csRef<iString>* failReason, csRef<iString>* tag, ProfileLimitsPair* cacheLimits) { if (!cache) return iShaderProgram::loadFail; csRef<iShaderProgramCG> prevCG (scfQueryInterfaceSafe<iShaderProgramCG> ( previous)); csRef<iStringArray> allCachedPrograms; if ((programType == progVP) && prevCG.IsValid()) { csShaderGLCGFP* prevFP = static_cast<csShaderGLCGFP*> ( (iShaderProgramCG*)prevCG); csString tagStr ("CG"); tagStr += prevFP->cacheLimits.ToString(); if (failReason) failReason->AttachNew ( new scfString ("paired cached programs not found")); allCachedPrograms.AttachNew (new scfStringArray); allCachedPrograms->Push (tagStr); } else allCachedPrograms = cache->GetSubItems ("/"); if (!allCachedPrograms.IsValid() || (allCachedPrograms->GetSize() == 0)) { if (failReason) failReason->AttachNew ( new scfString ("no cached programs found")); return iShaderProgram::loadFail; } if (!GetProgramNode (node)) return iShaderProgram::loadFail; csRef<iDataBuffer> programBuffer = GetProgramData(); CS::Utility::Checksum::MD5::Digest progHash = CS::Utility::Checksum::MD5::Encode ( programBuffer->GetData(), programBuffer->GetSize()); csArray<CachedShaderWrapper> cachedProgWrappers; for (size_t i = 0; i < allCachedPrograms->GetSize(); i++) { const char* tag = allCachedPrograms->Get (i); if ((tag[0] != 'C') || (tag[1] != 'G')) continue; CachedShaderWrapper wrapper; if (!wrapper.limits.FromString (tag+2)) continue; wrapper.name = tag; csString cachePath ("/"); cachePath.Append (tag); csRef<iDataBuffer> cacheBuf = cache->ReadCache (cachePath); if (!cacheBuf.IsValid()) continue; csRef<iFile> cacheFile; cacheFile.AttachNew (new csMemFile (cacheBuf, true)); wrapper.cacheFile = cacheFile; uint32 diskMagic; if (cacheFile->Read ((char*)&diskMagic, sizeof (diskMagic)) != sizeof (diskMagic)) continue; if (csLittleEndian::UInt32 (diskMagic) != cacheFileMagic) continue; CS::Utility::Checksum::MD5::Digest diskHash; if (cacheFile->Read ((char*)&diskHash, sizeof (diskHash)) != sizeof (diskHash)) continue; if (diskHash != progHash) continue; cachedProgWrappers.Push (wrapper); } if (cachedProgWrappers.GetSize() == 0) { if (failReason && !*failReason) failReason->AttachNew ( new scfString ("all cached programs failed to read")); return iShaderProgram::loadFail; } cachedProgWrappers.Sort (); ProfileLimits currentLimits ( (programType == progVP) ? shaderPlug->currentLimits.vp : shaderPlug->currentLimits.fp); bool strictMatch = (programType == progVP) ? shaderPlug->strictMatchVP : shaderPlug->strictMatchFP; const char* progTypeNode = 0; switch (programType) { case progVP: progTypeNode = "cgvp"; break; case progFP: progTypeNode = "cgfp"; break; } csString allReasons; bool oneReadCorrectly = false; ProfileLimits bestLimits ( CS::PluginCommon::ShaderProgramPluginGL::Other, CG_PROFILE_UNKNOWN); bool bestLimitsSet = false; for (size_t i = cachedProgWrappers.GetSize(); i-- > 0;) { const CachedShaderWrapper& wrapper = cachedProgWrappers[i]; const ProfileLimits& limits = (programType == progVP) ? wrapper.limits.vp : wrapper.limits.fp; if (!bestLimitsSet) { bestLimits = limits; bestLimitsSet = true; } if (strictMatch && (limits != currentLimits)) { allReasons += wrapper.name; allReasons += ": strict mismatch; "; continue; } bool profileSupported = (shaderPlug->ProfileNeedsRouting (limits.profile) && shaderPlug->IsRoutedProfileSupported (limits.profile)) || cgGLIsProfileSupported (limits.profile); if (!profileSupported) { allReasons += wrapper.name; allReasons += ": Profile unsupported; "; continue; } if ((limits.vendor != currentLimits.vendor) && (limits.vendor != CS::PluginCommon::ShaderProgramPluginGL::Other)) { allReasons += wrapper.name; allReasons += ": vendor mismatch; "; continue; } bool limitsSupported = currentLimits >= limits; if (!limitsSupported) { allReasons += wrapper.name; allReasons += ": Limits exceeded; "; continue; } iFile* cacheFile = wrapper.cacheFile; { uint32 diskState; if (cacheFile->Read ((char*)&diskState, sizeof (diskState)) != sizeof (diskState)) continue; if (csLittleEndian::UInt32 (diskState) != cpsValid) { oneReadCorrectly = true; continue; } } description = CS::PluginCommon::ShaderCacheHelper::ReadString (cacheFile); bool breakFail = false; csRef<iDocumentNode> cgNode = node->GetNode (progTypeNode); if (!cgNode.IsValid()) continue; csRef<iDocumentNodeIterator> nodes = cgNode->GetNodes(); while(nodes->HasNext() && !breakFail) { csRef<iDocumentNode> child = nodes->Next(); if(child->GetType() != CS_NODE_ELEMENT) continue; const char* value = child->GetValue (); csStringID id = xmltokens.Request (value); switch(id) { case XMLTOKEN_VARIABLEMAP: if (!ParseVmap (child)) breakFail = true; break; case XMLTOKEN_CLIP: if (!ParseClip (child)) breakFail = true; break; default: /* Ignore unknown nodes. Invalid nodes would have been caught by the first (not from cache) parsing */ break; } } if (breakFail) continue; csString objectCodeCachePathArc = CS::PluginCommon::ShaderCacheHelper::ReadString (cacheFile); if (objectCodeCachePathArc.IsEmpty()) continue; csString objectCodeCachePathItem = CS::PluginCommon::ShaderCacheHelper::ReadString (cacheFile); if (objectCodeCachePathItem.IsEmpty()) continue; ProgramObjectID progId (objectCodeCachePathArc, objectCodeCachePathItem); ProgramObject programObj; //if (!LoadObjectCodeFromCompileCache (limits, cache)) if (!shaderPlug->progCache.LoadObject (progId, programObj)) continue; oneReadCorrectly = true; if (program) { cgDestroyProgram (program); program = 0; } if (!programObj.IsValid()) continue; cgGetError(); // Clear error program = cgCreateProgram (shaderPlug->context, CG_OBJECT, programObj.GetObjectCode(), limits.profile, 0, 0); if (!program) continue; CGerror err = cgGetError(); if (err != CG_NO_ERROR) { const char* errStr = cgGetErrorString (err); shaderPlug->Report (CS_REPORTER_SEVERITY_WARNING, "Cg error %s", errStr); continue; } programProfile = limits.profile; programPositionInvariant = programObj.GetFlags() & ProgramObject::flagPositionInvariant; unusedParams = programObj.GetUnusedParams(); ClipsToVmap(); GetParamsFromVmap(); bool doLoadToGL = !shaderPlug->ProfileNeedsRouting (programProfile); cgGetError(); // Clear error if (doLoadToGL) { cgGLLoadProgram (program); } else { cgCompileProgram (program); } shaderPlug->PrintAnyListing(); err = cgGetError(); if ((err != CG_NO_ERROR) || (doLoadToGL && !cgGLIsProgramLoaded (program))) { //if (shaderPlug->debugDump) //DoDebugDump(); const char* errStr = cgGetErrorString (err); shaderPlug->Report (CS_REPORTER_SEVERITY_WARNING, "Cg error %s", errStr); if (shaderPlug->doVerbose && (((programType == progVP) && (programProfile >= CG_PROFILE_ARBVP1)) || ((programType == progFP) && (programProfile >= CG_PROFILE_ARBFP1)))) { const char* err = (char*)glGetString (GL_PROGRAM_ERROR_STRING_ARB); shaderPlug->Report (CS_REPORTER_SEVERITY_WARNING, "OpenGL error string: %s", err); } shaderPlug->SetCompiledSource (0); continue; } GetPostCompileParamProps (); if (shaderPlug->debugDump) DoDebugDump(); tag->AttachNew (new scfString (wrapper.name)); if (cacheLimits != 0) *cacheLimits = wrapper.limits; bool loaded = !shaderPlug->ProfileNeedsRouting (programProfile) || LoadProgramWithPS1 (); if (loaded && (bestLimits < currentLimits)) { /* The best found program is worse than the current limits, so pretend that the shader program failed (instead just being 'invalid') - that will make xmlshader try to load the program from scratch, ie with current limits, which may just work. */ if (failReason) failReason->AttachNew (new scfString ("Provoking clean load with current limits")); return iShaderProgram::loadFail; } return loaded ? iShaderProgram::loadSuccessShaderValid : iShaderProgram::loadSuccessShaderInvalid; } if (oneReadCorrectly) { if (bestLimits < currentLimits) { /* The 'invalid' programs may compile with the current limits - so again, provoke clean load */ if (failReason) failReason->AttachNew (new scfString ("Provoking clean load with current limits")); return iShaderProgram::loadFail; } else return iShaderProgram::loadSuccessShaderInvalid; } else return iShaderProgram::loadFail; }
bool cgShader::Reload(){ for(int k = 0; k < 3; k++){ if(cgProgram[k]){ cgDestroyProgram(cgProgram[k]); } } cgProfile[0] = cgProfile[1] = cgProfile[2] = CG_PROFILE_UNKNOWN; cgProgram[0] = cgProgram[1] = cgProgram[2] = NULL; bool ret = true; if(cgGetContext()){ for(int i = 0; i < 3; i++){ if(i == 0 && vpmain == 0){ continue; } if(i == 1 && gpmain == 0){ continue; } if(i == 2 && fpmain == 0){ continue; } switch(i){ case 0: cgProfile[i] = cgGLGetLatestProfile(CG_GL_VERTEX); break; case 1: cgProfile[i] = cgGLGetLatestProfile(CG_GL_GEOMETRY); break; case 2: cgProfile[i] = cgGLGetLatestProfile(CG_GL_FRAGMENT); break; } if (cgProfile[i] == CG_PROFILE_UNKNOWN){ printf("Invalid profile type ("); switch(i){ case 0: printf("CG_GL_VERTEX)\n"); break; case 1: printf("CG_GL_GEOMETRY)\n"); break; case 2: printf("CG_GL_FRAGMENT)\n"); break; } ret = false; continue; } cgGLSetOptimalOptions(cgProfile[i]); if(code){ switch(i){ case 0: cgProgram[i] = cgCreateProgram(cgGetContext(), CG_SOURCE, code, cgProfile[i], vpmain, 0); break; case 1: cgProgram[i] = cgCreateProgram(cgGetContext(), CG_SOURCE, code, cgProfile[i], gpmain, 0); break; case 2: cgProgram[i] = cgCreateProgram(cgGetContext(), CG_SOURCE, code, cgProfile[i], fpmain, 0); break; } } else{ switch(i){ case 0: cgProgram[i] = cgCreateProgramFromFile(cgGetContext(), CG_SOURCE, fname, cgProfile[i], vpmain, 0); break; case 1: cgProgram[i] = cgCreateProgramFromFile(cgGetContext(), CG_SOURCE, fname, cgProfile[i], gpmain, 0); break; case 2: cgProgram[i] = cgCreateProgramFromFile(cgGetContext(), CG_SOURCE, fname, cgProfile[i], fpmain, 0); break; } } if (cgProgram[i] == NULL){ switch(i){ case 0: printf("CG ERROR (VERTEX) : %s\n", cgGetErrorString(cgGetError())); break; case 1: printf("CG ERROR (GEOMETRY) : %s\n",cgGetErrorString(cgGetError())); break; case 2: printf("CG ERROR (FRAGMENT) : %s\n",cgGetErrorString(cgGetError())); break; } ret = false; continue; } cgGLLoadProgram(cgProgram[i]); } } if(loaded){ if(ret){ printf("INFO (cgShader): Reloaded %s successfully\n",fname); } else{ printf("INFO (cgShader): Reloading %s failed\n",fname); } } else{ if(ret){ printf("INFO (cgShader): Loaded %s successfully\n",fname); } else{ printf("INFO (cgShader): Loading %s failed\n",fname); } } loaded = true; return ret; }
bool cgShader_3::Reload(){ for(int k = 0; k < 5; k++){ if(cgProgram[k]){ cgDestroyProgram(cgProgram[k]); } cgProfile[k] = CG_PROFILE_UNKNOWN; cgProgram[k] = NULL; } bool ret = true; if(cgGetContext()){ for(int i = 0; i < 5; i++){ if( main[i] == 0 ){ continue; } switch(i){ case 0: cgProfile[i] = cgGLGetLatestProfile(CG_GL_VERTEX); break; case 1: cgProfile[i] = cgGLGetLatestProfile(CG_GL_TESSELLATION_CONTROL); break; case 2: cgProfile[i] = cgGLGetLatestProfile(CG_GL_TESSELLATION_EVALUATION); break; case 3: cgProfile[i] = cgGLGetLatestProfile(CG_GL_GEOMETRY); break; case 4: cgProfile[i] = cgGLGetLatestProfile(CG_GL_FRAGMENT); break; } if (cgProfile[i] == CG_PROFILE_UNKNOWN){ printf("Invalid profile type ("); switch(i){ case 0: printf("CG_GL_VERTEX)\n"); break; case 1: printf("CG_GL_TESSELLATION_CONTROL)\n"); break; case 2: printf("CG_GL_TESSELLATION_EVALUATION)\n"); break; case 3: printf("CG_GL_GEOMETRY)\n"); break; case 4: printf("CG_GL_FRAGMENT)\n"); break; } ret = false; continue; } cgGLSetOptimalOptions(cgProfile[i]); if(code){ cgProgram[i] = cgCreateProgram(cgGetContext(), CG_SOURCE, code, cgProfile[i], main[i], 0); } else{ cgProgram[i] = cgCreateProgramFromFile(cgGetContext(), CG_SOURCE, fname, cgProfile[i], main[i], 0); } if (cgProgram[i] == NULL){ switch(i){ case 0: printf("CG ERROR (VERTEX) : %s\n", cgGetErrorString(cgGetError())); break; case 1: printf("CG ERROR (TESS_CTRL) : %s\n",cgGetErrorString(cgGetError())); break; case 2: printf("CG ERROR (TESS_EVAL) : %s\n",cgGetErrorString(cgGetError())); break; case 3: printf("CG ERROR (GEOMETRY) : %s\n", cgGetErrorString(cgGetError())); break; case 4: printf("CG ERROR (FRAGMENT) : %s\n", cgGetErrorString(cgGetError())); break; } ret = false; continue; } cgGLLoadProgram(cgProgram[i]); } } if(loaded){ if(ret){ printf("INFO (cgShader): Reloaded %s successfully\n",fname); } else{ printf("INFO (cgShader): Reloading %s failed\n",fname); } } else{ if(ret){ printf("INFO (cgShader): Loaded %s successfully\n",fname); } else{ printf("INFO (cgShader): Loading %s failed\n",fname); } } loaded = true; return ret; }