void csShaderGLCGCommon::DebugDumpParam (csString& output, CGparameter param) { output << "Parameter: " << cgGetParameterName (param) << "\n"; output << " Type: " << cgGetTypeString (cgGetParameterNamedType (param)) << "\n"; output << " Direction: " << cgGetEnumString (cgGetParameterDirection (param)) << "\n"; output << " Semantic: " << cgGetParameterSemantic (param) << "\n"; const CGenum var = cgGetParameterVariability (param); output << " Variability: " << cgGetEnumString (var) << "\n"; output << " Resource: " << cgGetResourceString (cgGetParameterResource (param)) << "\n"; output << " Resource index: " << cgGetParameterResourceIndex (param) << "\n"; // Cg 2.0 seems to not like CG_DEFAULT for uniforms if (/*(var == CG_UNIFORM) || */(var == CG_CONSTANT)) { int nValues; const double* values = cgGetParameterValues (param, (var == CG_UNIFORM) ? CG_DEFAULT : CG_CONSTANT, &nValues); if (nValues != 0) { output << " Values:"; for (int v = 0; v < nValues; v++) { output << ' ' << values[v]; } output << "\n"; } } if (!cgIsParameterUsed (param, program)) output << " not used\n"; if (!cgIsParameterReferenced (param)) output << " not referenced\n"; }
void SetupVertexProgramParameters(ZZshProgram prog, int context) { ZZshParameter p; p = cgGetNamedParameter(prog, "g_fPosXY"); if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) cgConnectParameter(g_vparamPosXY[context], p); // Set Z-test, log or no log; if (conf.settings().no_logz) { g_vdepth = float4( 255.0 /256.0f, 255.0/65536.0f, 255.0f/(65535.0f*256.0f), 1.0f/(65536.0f*65536.0f)); vlogz = float4( 1.0f, 0.0f, 0.0f, 0.0f); } else { g_vdepth = float4( 256.0f*65536.0f, 65536.0f, 256.0f, 65536.0f*65536.0f); vlogz = float4( 0.0f, 1.0f, 0.0f, 0.0f); } p = cgGetNamedParameter(prog, "g_fZ"); if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) { cgGLSetParameter4fv(p, g_vdepth); p = cgGetNamedParameter(prog, "g_fZMin"); // Switch to flat-z when needed if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) { //ZZLog::Error_Log("Use flat-z\n"); cgGLSetParameter4fv(p, vlogz); } else ZZLog::Error_Log("Shader file version is outdated! Only log-Z is possible."); } float4 vnorm = float4(g_filog32, 0, 0,0); p = cgGetNamedParameter(prog, "g_fZNorm"); if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) cgGLSetParameter4fv(p, vnorm); p = cgGetNamedParameter(prog, "g_fBilinear"); if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) cgGLSetParameter4fv(p, float4(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f )); p = cgGetNamedParameter(prog, "g_fZBias"); if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) cgGLSetParameter4fv(p, float4(1.0f/256.0f, 1.0004f, 1, 0.5f)); p = cgGetNamedParameter(prog, "g_fc0"); if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) cgGLSetParameter4fv(p, float4(0,1, 0.001f, 0.5f)); }
static bool AddPass(CGtechnique technique, JSON &json, CGpass pass, UniformsMap &uniformRemapping) { bool success = true; json.AddObject(NULL); const char * const passName = cgGetPassName(pass); if (NULL != passName) { json.AddString("name", passName); } bool firstParameter = true; #if CG_VERSION_NUM >= 3000 const int CG_NUMBER_OF_DOMAINS = (CG_TESSELLATION_EVALUATION_DOMAIN + 1); #endif for (int domain = CG_FIRST_DOMAIN; domain < CG_NUMBER_OF_DOMAINS; domain++) { const CGprogram program = cgGetPassProgram(pass, (CGdomain)domain); if (NULL != program) { const char * const programString = cgGetProgramString(program, CG_COMPILED_PROGRAM); CGparameter param = cgGetFirstParameter(program, CG_GLOBAL); while (NULL != param) { if (cgIsParameterUsed(param, program) && CG_UNIFORM == cgGetParameterVariability(param)) { if (firstParameter) { firstParameter = false; json.AddArray("parameters", true); json.BeginData(true); } const char * const paramName = cgGetParameterName(param); AddMappedParameter(json, paramName, programString, uniformRemapping); } param = cgGetNextParameter(param); } param = cgGetFirstParameter(program, CG_PROGRAM); while (NULL != param) { if (cgIsParameterUsed(param, program) && CG_UNIFORM == cgGetParameterVariability(param)) { if (firstParameter) { firstParameter = false; json.AddArray("parameters", true); json.BeginData(true); } const char * const paramName = cgGetParameterName(param); AddMappedParameter(json, paramName, programString, uniformRemapping); } param = cgGetNextParameter(param); } } } if (!firstParameter) { json.EndData(); json.CloseArray(true); // parameters } json.AddArray("semantics", true); json.BeginData(true); CGprogram vertexProgram = cgGetPassProgram(pass, CG_VERTEX_DOMAIN); CGparameter vertexInputParameter = cgGetFirstLeafParameter(vertexProgram, CG_PROGRAM); while (NULL != vertexInputParameter) { const CGenum variability = cgGetParameterVariability(vertexInputParameter); if (CG_VARYING == variability) { const CGenum direction = cgGetParameterDirection(vertexInputParameter); if (CG_IN == direction || CG_INOUT == direction) { const char * const semantic = cgGetParameterSemantic(vertexInputParameter); json.AddData(semantic, strlen(semantic)); } } vertexInputParameter = cgGetNextLeafParameter(vertexInputParameter); } json.EndData(); json.CloseArray(true); // semantics json.AddObject("states"); CGstateassignment state = cgGetFirstStateAssignment(pass); if (NULL != state) { do { success &= AddState(json, state); state = cgGetNextStateAssignment(state); } while (NULL != state); } json.CloseObject(); // states json.AddArray("programs", true); json.BeginData(true); for (int domain = CG_FIRST_DOMAIN; domain < CG_NUMBER_OF_DOMAINS; domain++) { const CGprogram program = cgGetPassProgram(pass, (CGdomain)domain); if (NULL != program) { const char * const entryPoint = cgGetProgramString(program, CG_PROGRAM_ENTRY); json.AddData(entryPoint, strlen(entryPoint)); } else if (domain == CG_VERTEX_DOMAIN) { ErrorMessage("%s : No vertex program.", cgGetTechniqueName(technique)); success = false; } else if(domain == CG_FRAGMENT_DOMAIN) { ErrorMessage("%s : No fragment program.", cgGetTechniqueName(technique)); success = false; } } json.EndData(); json.CloseArray(true); // programs json.CloseObject(); // pass return success; }
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; }
void SetupFragmentProgramParameters(FRAGMENTSHADER* pf, int context, int type) { // uniform parameters ZZshParameter p; p = cgGetNamedParameter(pf->prog, "g_fFogColor"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) { cgConnectParameter(g_fparamFogColor, p); } SET_UNIFORMPARAM(sOneColor, "g_fOneColor"); SET_UNIFORMPARAM(sBitBltZ, "g_fBitBltZ"); SET_UNIFORMPARAM(sInvTexDims, "g_fInvTexDims"); SET_UNIFORMPARAM(fTexAlpha2, "fTexAlpha2"); SET_UNIFORMPARAM(fTexOffset, "g_fTexOffset"); SET_UNIFORMPARAM(fTexDims, "g_fTexDims"); SET_UNIFORMPARAM(fTexBlock, "g_fTexBlock"); SET_UNIFORMPARAM(fClampExts, "g_fClampExts"); SET_UNIFORMPARAM(fTexWrapMode, "TexWrapMode"); SET_UNIFORMPARAM(fRealTexDims, "g_fRealTexDims"); SET_UNIFORMPARAM(fTestBlack, "g_fTestBlack"); SET_UNIFORMPARAM(fPageOffset, "g_fPageOffset"); SET_UNIFORMPARAM(fTexAlpha, "fTexAlpha"); // textures p = cgGetNamedParameter(pf->prog, "g_sBlocks"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) { cgGLSetTextureParameter(p, ptexBlocks); cgGLEnableTextureParameter(p); } // cg parameter usage is wrong, so do it manually if( type == 3 ) { p = cgGetNamedParameter(pf->prog, "g_sConv16to32"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) { cgGLSetTextureParameter(p, ptexConv16to32); cgGLEnableTextureParameter(p); } } else if( type == 4 ) { p = cgGetNamedParameter(pf->prog, "g_sConv32to16"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) { cgGLSetTextureParameter(p, ptexConv32to16); cgGLEnableTextureParameter(p); } } else { p = cgGetNamedParameter(pf->prog, "g_sBilinearBlocks"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) { cgGLSetTextureParameter(p, ptexBilinearBlocks); cgGLEnableTextureParameter(p); } } p = cgGetNamedParameter(pf->prog, "g_sMemory"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) { //cgGLEnableTextureParameter(p); pf->sMemory = p; } p = cgGetNamedParameter(pf->prog, "g_sSrcFinal"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) { //cgGLEnableTextureParameter(p); pf->sFinal = p; } p = cgGetNamedParameter(pf->prog, "g_sBitwiseANDX"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) { //cgGLEnableTextureParameter(p); pf->sBitwiseANDX = p; } p = cgGetNamedParameter(pf->prog, "g_sBitwiseANDY"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) { //cgGLEnableTextureParameter(p); pf->sBitwiseANDY = p; } p = cgGetNamedParameter(pf->prog, "g_sCLUT"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) { //cgGLEnableTextureParameter(p); pf->sCLUT = p; } p = cgGetNamedParameter(pf->prog, "g_sInterlace"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) { //cgGLEnableTextureParameter(p); pf->sInterlace = p; } // set global shader constants p = cgGetNamedParameter(pf->prog, "g_fExactColor"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) { cgGLSetParameter4fv(p, float4(0.5f, (conf.settings().exact_color)?0.9f/256.0f:0.5f/256.0f, 0,1/255.0f)); } p = cgGetNamedParameter(pf->prog, "g_fBilinear"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) cgGLSetParameter4fv(p, float4(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f )); p = cgGetNamedParameter(pf->prog, "g_fZBias"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) cgGLSetParameter4fv(p, float4(1.0f/256.0f, 1.0004f, 1, 0.5f)); p = cgGetNamedParameter(pf->prog, "g_fc0"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) cgGLSetParameter4fv(p, float4(0,1, 0.001f, 0.5f)); p = cgGetNamedParameter(pf->prog, "g_fMult"); if( p != NULL && cgIsParameterUsed(p, pf->prog) == CG_TRUE ) cgGLSetParameter4fv(p, float4(1/1024.0f, 0.2f/1024.0f, 1/128.0f, 1/512.0f)); }