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; }
static HRESULT CALLBACK OnResetDevice(IDirect3DDevice9* pDev, const D3DSURFACE_DESC* backBuf, void* userContext) { cgD3D9SetDevice(pDev); checkForCgError("setting Direct3D device"); static int firstTime = 1; if (firstTime) { /* Cg runtime resources such as CGprogram and CGparameter handles survive a device reset so we just need to compile a Cg program just once. We do however need to unload Cg programs with cgD3DUnloadProgram upon when a Direct3D device is lost and load Cg programs every Direct3D device reset with cgD3D9UnloadProgram. */ createCgPrograms(); firstTime = 0; } /* false below means "no parameter shadowing" */ cgD3D9LoadProgram(g_cgVertexProgram, false, 0); checkForCgError("loading vertex program"); bool bRet; bRet = init(pDev); if (bRet) return S_OK; else return S_FALSE; }
//--------------------------------------------------------------------------------- // 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; }
void CD3D9CgMaterialRenderer::init(s32& pMaterialType, const c8* pVertexProgram, const c8* pVertexEntry, E_VERTEX_SHADER_TYPE pVertexProfile, const c8* pFragmentProgram, const c8* pFragmentEntry, E_PIXEL_SHADER_TYPE pFragmentProfile, const c8* pGeometryProgram, const c8* pGeometryEntry, E_GEOMETRY_SHADER_TYPE pGeometryProfile, scene::E_PRIMITIVE_TYPE pInType, scene::E_PRIMITIVE_TYPE pOutType, u32 pVertices) { bool Status = true; CGerror Error = CG_NO_ERROR; pMaterialType = -1; // TODO: add profile selection if (pVertexProgram) { VertexProfile = cgD3D9GetLatestVertexProfile(); if (VertexProfile) VertexProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pVertexProgram, VertexProfile, pVertexEntry, 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 cgD3D9LoadProgram(VertexProgram, 0, 0); } if (pFragmentProgram) { FragmentProfile = cgD3D9GetLatestPixelProfile(); if (FragmentProfile) FragmentProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pFragmentProgram, FragmentProfile, pFragmentEntry, 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 cgD3D9LoadProgram(FragmentProgram, 0, 0); } /*if (pGeometryProgram) { GeometryProfile = cgD3D9GetLatestGeometryProfile(); if (GeometryProfile) GeometryProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pGeometryProgram, GeometryProfile, pGeometryEntry, 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 cgD3D9LoadProgram(GeometryProgram, 0, 0); }*/ getUniformList(); // create D3D9 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 CD3D9CgUniformSampler2D(UniformInfo[i]->getParameter(), IsGlobal); delete UniformInfo[i]; UniformInfo[i] = Uniform; } } if (Status) pMaterialType = Driver->addMaterialRenderer(this); }
bool CD3DCG::LoadShader(const TCHAR *shaderFile) { CCGShader cgShader; TCHAR shaderPath[MAX_PATH]; TCHAR tempPath[MAX_PATH]; HRESULT hr; GLenum error; ClearPasses(); if (shaderFile == NULL || *shaderFile==TEXT('\0')) return true; lstrcpy(shaderPath,shaderFile); for(int i=lstrlen(shaderPath); i>=0; i--){ if(IS_SLASH(shaderPath[i])){ shaderPath[i]=TEXT('\0'); break; } } SetCurrentDirectory(shaderPath); if(!cgShader.LoadShader(_tToChar(shaderFile))) return false; CGprofile vertexProfile = cgD3D9GetLatestVertexProfile(); CGprofile pixelProfile = cgD3D9GetLatestPixelProfile(); const char** vertexOptions = cgD3D9GetOptimalOptions(vertexProfile); const char** pixelOptions = cgD3D9GetOptimalOptions(pixelProfile); 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; } // paths in the meta file can be relative _tfullpath(tempPath,_tFromChar(it->cgShaderFile),MAX_PATH); char *fileContents = ReadShaderFileContents(tempPath); if(!fileContents) return false; pass.cgVertexProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents, vertexProfile, "main_vertex", vertexOptions); checkForCgError("Compiling vertex program"); pass.cgFragmentProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents, pixelProfile, "main_fragment", pixelOptions); checkForCgError("Compiling fragment program"); delete [] fileContents; if(!pass.cgVertexProgram || !pass.cgFragmentProgram) { return false; } if(pass.cgVertexProgram) { hr = cgD3D9LoadProgram(pass.cgVertexProgram,false,0); } checkForCgError("Loading vertex program"); if(pass.cgFragmentProgram) { hr = cgD3D9LoadProgram(pass.cgFragmentProgram,false,0); } checkForCgError("Loading fragment program"); /* generate vertex buffer */ hr = pDevice->CreateVertexBuffer(sizeof(VERTEX)*4,D3DUSAGE_WRITEONLY,0,D3DPOOL_MANAGED,&pass.vertexBuffer,NULL); if(FAILED(hr)) { pass.vertexBuffer = NULL; DXTRACE_ERR_MSGBOX(TEXT("Error creating vertex buffer"), hr); return false; } /* set up vertex declarations for the pass, this also creates the vertex declaration */ setupVertexDeclaration(pass); 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); tex.linearFilter = it->linearfilter; _tfullpath(tempPath,_tFromChar(it->texturePath),MAX_PATH); hr = D3DXCreateTextureFromFileEx( pDevice, tempPath, D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, 0, 0, D3DFMT_FROM_FILE, D3DPOOL_MANAGED, it->linearfilter?D3DX_FILTER_LINEAR:D3DX_FILTER_POINT, 0, 0, NULL, NULL, &tex.tex); if FAILED(hr){ tex.tex = NULL; } lookupTextures.push_back(tex); } shaderLoaded = true; return true; }