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";
}
Example #2
0
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));
}
Example #3
0
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;
}
Example #5
0
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));
}