예제 #1
0
ShaderPair::~ShaderPair()
{
	if (cgIsProgram(m_vert))
		cgDestroyProgram(m_vert);
	if (cgIsProgram(m_frag))
		cgDestroyProgram(m_frag);
}
예제 #2
0
    //
    // Link
    //
    void CCgShadingProgram::Link()
    {
        m_UniformCache.clear();
        m_SamplerUniformCache.clear();
        m_BindableUniformCache.clear();
    
        //m_Samplers.clear();

        if (cgIsProgram( m_Program ))
            cgDestroyProgram( m_Program );
            
        if (m_Shaders.size() == 1)
            m_Program = m_Shaders[ 0 ]->m_Program;
        else
        {
            vector<CGprogram> Programs;

            for (CONST_VECTOR_ITERATION( Ptr<const CCgShader>, m_Shaders, i ))
                Programs.push_back( (*i)->m_Program );
                
            m_Program = cgCombinePrograms( static_cast<int>( Programs.size() ), &Programs[ 0 ] );
            CGerror Error = cgGetError();
            if (Error != CG_NO_ERROR)
                throw CCgException( this, Error, "::Link() : Failed to combine Cg program." );
        }

        cgGLLoadProgram( m_Program );
        CGerror Error = cgGetError();
        if (Error != CG_NO_ERROR)
            throw CCgException( this, Error, "::Link() : Failed to load Cg program. Program may fails to load for any reason." );

         sort( m_Profiles.begin(), m_Profiles.end() );
    }
예제 #3
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);
	}
예제 #4
0
    //
    // Destructor
    //
    CCgShadingProgram::~CCgShadingProgram()
    {
        if (cgIsProgram( m_Program ))
            cgDestroyProgram( m_Program );

        CCgContext::Release();
    }
예제 #5
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;
}
예제 #6
0
	IOGLBaseShader::~IOGLBaseShader(){
		this->UnbindParameters();
		this->UnbindSamplers();
		if(this->m_bBinded){
			this->Unbind();
		}
		if(this->m_uProgram != 0 && cgIsProgram(this->m_uProgram)){
			cgDestroyProgram(this->m_uProgram);
			this->m_uProgram = 0;
		}
	}
예제 #7
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));	
}
예제 #8
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);
}
예제 #9
0
bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram)
{
	GLenum err = GL_REPORT_ERROR();
	if (err != GL_NO_ERROR)
	{
		ERROR_LOG(VIDEO, "glError %08x before PS!", err);
	}

#if defined HAVE_CG && HAVE_CG
	char stropt[128];
	sprintf(stropt, "MaxLocalParams=224,NumInstructionSlots=%d", s_nMaxPixelInstructions);
	const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL};
	CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts);

	// handle errors
	if (!cgIsProgram(tempprog))
	{
		cgDestroyProgram(tempprog);

		static int num_failures = 0;
		char szTemp[MAX_PATH];
		sprintf(szTemp, "%sbad_ps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++);
		std::ofstream file(szTemp);
		file << pstrprogram;
		file.close();

		PanicAlert("Failed to compile pixel shader!\nThis usually happens when trying to use Dolphin with an outdated GPU or integrated GPU like the Intel GMA series.\n\nIf you're sure this is Dolphin's error anyway, post the contents of %s along with this error message at the forums.\n\nDebug info (%d):\n%s",
						szTemp,
						g_cgfProf,
						cgGetLastListing(g_cgcontext));

		return false;
	}

	// handle warnings
	if (cgGetError() != CG_NO_ERROR)
	{
		WARN_LOG(VIDEO, "Warnings on compile ps %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, &ps.glprogid);
	SetCurrentShader(ps.glprogid);	
	glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog);

	err = GL_REPORT_ERROR();
	if (err != GL_NO_ERROR)
	{
		GLint error_pos, native_limit;
		glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos);
		glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &native_limit);
		// Error occur
		if (error_pos != -1) {
			const char *program_error = (const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB);
			char line[256];
			strncpy(line, (const char *)pcompiledprog + error_pos, 255);
			line[255] = 0;
			ERROR_LOG(VIDEO, "Error at %i: %s", error_pos, program_error);
			ERROR_LOG(VIDEO, "Line dump: \n%s", line);
		} else if (native_limit != -1) {
			ERROR_LOG(VIDEO, "Hit limit? %i", native_limit);
			// TODO
		}
		ERROR_LOG(VIDEO, "%s", pstrprogram);
		ERROR_LOG(VIDEO, "%s", pcompiledprog);
	}

	cgDestroyProgram(tempprog);
#endif

	return true;
}
예제 #10
0
    //
    // Constructor
    //
    CCgShader::CCgShader( 
                         CGenum SourceType, const string& SourceStr, CGprofile Profile, CGGLenum ProfileClass,
                         const string& Entry, const string& Arguments
                         ):
        m_Program( NULL )
    {
        if (SourceType != CG_SOURCE && SourceType != CG_OBJECT)
            throw Sys::CDeveloperException( "GL::CCgShader", "::CCgShader() : Invalid <SourceType> parameter." );
        if (SourceStr.length() == 0)
            throw Sys::CDeveloperException( "GL::CCgShader", "::CCgShader() : Invalid <SourceStr> parameter." );

        CCgContext::AddRef();

        if (Profile == CG_PROFILE_UNKNOWN)
            Profile = cgGLGetLatestProfile( ProfileClass );
        else 
        {
            CheckDomain( Profile, ProfileClass );
            if (cgGLIsProfileSupported( Profile ) == CG_FALSE)
            {
                const char *ProfileName = GetProfileName( Profile );
                if (!ProfileName)
                    throw Sys::CException( 0, "GL::CCgShader", "::CCgShader() : Unknown shader profile." );
                else
                {
                    throw Sys::CException( 0, "GL::CCgShader", "::CCgShader() : Profile %s unsupported.\n"
                        "A profile may not be supported if required OpenGL extension is not available.", ProfileName );
                }
            }
        }

        try
        {
            const char *TypeName = NULL;
            switch (ProfileClass)
            {
            case CG_GL_VERTEX:
                TypeName = "vertex";
                break;
            case CG_GL_GEOMETRY:
                TypeName = "geometry";
                break;
            case CG_GL_FRAGMENT:
                TypeName = "fragment";
                break;
            }

            const char *Args[ 2 ] =
            {
                Arguments.c_str(),
                NULL
            };
            
            m_Program = cgCreateProgram( CCgContext::GetContext(), SourceType, SourceStr.c_str(), Profile, 
                (Entry.length() == 0) ? NULL : Entry.c_str(), (Arguments.length() == 0) ? NULL : Args );
            if (!m_Program)
            {
                m_LastListing = CCgContext::GetLastListing();
    #ifdef _DEBUG
                OutputDebugLog();
    #endif
                throw CCgException( "GL::CCgShader", cgGetError(), "::CCgShader() : Failed to create Cg %s shader.\nSee program log for more details.", TypeName );
            }

            cgCompileProgram( m_Program );
            CGerror Error = cgGetError();
            if (Error != CG_NO_ERROR)
            {
                m_LastListing = CCgContext::GetLastListing();
    #ifdef _DEBUG
                OutputDebugLog();
    #endif
                throw CCgException( "GL::CCgShader", Error, "::CCgShader() : Failed to compile Cg %s shader.\nSee program log for more details.", TypeName );
            }
        }
        catch (const Sys::CException& Ex)
        {
            if (cgIsProgram( m_Program ))
                cgDestroyProgram( m_Program );

            CCgContext::Release();

            throw Ex;
        }
    }
예제 #11
0
FRAGMENTSHADER* ZZshLoadShadeEffect(int type, int texfilter, int fog, int testaem, int exactcolor, const clampInfo& clamp, int context, bool* pbFailed)
{
	int texwrap;
	assert( texfilter < NUM_FILTERS );

	if(g_nPixelShaderVer&SHADER_REDUCED)
		texfilter = 0;
	assert(!(g_nPixelShaderVer&SHADER_REDUCED) || !exactcolor);

	if( clamp.wms == clamp.wmt ) {
		switch( clamp.wms ) {
			case 0: texwrap = TEXWRAP_REPEAT; break;
			case 1: texwrap = TEXWRAP_CLAMP; break;
			case 2: texwrap = TEXWRAP_CLAMP; break;
			default: texwrap = TEXWRAP_REGION_REPEAT; break;
		}
	}
	else if( clamp.wms==3||clamp.wmt==3)
		texwrap = TEXWRAP_REGION_REPEAT;
	else
		texwrap = TEXWRAP_REPEAT_CLAMP;

	int index = GET_SHADER_INDEX(type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, context, 0);

	assert( index < ArraySize(ppsTexture) );
	FRAGMENTSHADER* pf = ppsTexture+index;

	if( pbFailed != NULL ) *pbFailed = false;

	if( pf->prog != NULL )
		return pf;

	if( (g_nPixelShaderVer & SHADER_ACCURATE) && mapShaderResources.find(index+NUM_SHADERS*SHADER_ACCURATE) != mapShaderResources.end() )
		index += NUM_SHADERS*SHADER_ACCURATE;

	assert( mapShaderResources.find(index) != mapShaderResources.end() );
	SHADERHEADER* header = mapShaderResources[index];
	if( header == NULL )
		ZZLog::Error_Log("%d %d", index, g_nPixelShaderVer);
	assert( header != NULL );

	//DEBUG_LOG("shader:\n%s\n", (char*)(s_lpShaderResources + (header)->offset));
	pf->prog = cgCreateProgram(g_cgcontext, CG_OBJECT, (char*)(s_lpShaderResources + (header)->offset), cgfProf, NULL, NULL);
	if( pf->prog != NULL && cgIsProgram(pf->prog) && cgGetError() == CG_NO_ERROR ) {
		SetupFragmentProgramParameters(pf, context, type);
		cgGLLoadProgram(pf->prog);
		if( cgGetError() != CG_NO_ERROR ) {
//		  cgGLLoadProgram(pf->prog);
//		  if( cgGetError() != CG_NO_ERROR ) {
				ZZLog::Error_Log("Failed to load shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms+clamp.wmt);
				if( pbFailed != NULL ) *pbFailed = true;
				return pf;
//		  }
		}
		return pf;
	}

	ZZLog::Error_Log("Failed to create shader %d,%d,%d,%d", type, fog, texfilter, 4*clamp.wms+clamp.wmt);
	if( pbFailed != NULL ) *pbFailed = true;

	return NULL;
}