예제 #1
0
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;
}
예제 #2
0
파일: Scene.cpp 프로젝트: andyreimann/gear
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);

}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
    //-----------------------------------------------------------------------
    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);

    }
예제 #7
0
	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);
	}
예제 #8
0
 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;;
 }
예제 #9
0
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;
}
예제 #10
0
파일: shader_cg.c 프로젝트: AreaScout/retro
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;
}
예제 #11
0
파일: Shader.cpp 프로젝트: kuro/fyreware
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;
	}
예제 #13
0
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));	
}
예제 #14
0
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;
}
예제 #15
0
 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;
 }
예제 #16
0
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);
}
예제 #17
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;
}
예제 #18
0
파일: RendererGL.cpp 프로젝트: 183amir/kge
	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;

	}
예제 #19
0
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
}
예제 #20
0
파일: RendererGL.cpp 프로젝트: 183amir/kge
	// 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
예제 #21
0
	//-----------------------------------------------------------------------
	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);
}
예제 #23
0
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;
}
예제 #24
0
파일: CGLCG.cpp 프로젝트: RedGuyyyy/snes9x
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;
}
예제 #25
0
//---------------------------------------------------------------------------------
// 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;
}
예제 #27
0
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;
}
예제 #28
0
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;
}
예제 #29
0
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;
}
예제 #30
0
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;
}