Exemplo n.º 1
0
void TranslateToGLSL(HLSLCrossCompilerContext* psContext, GLLang* planguage,const GlExtensions *extensions)
{
    bstring glsl;
    uint32_t i;
    Shader* psShader = psContext->psShader;
    GLLang language = *planguage;
    const uint32_t ui32InstCount = psShader->ui32InstCount;
    const uint32_t ui32DeclCount = psShader->ui32DeclCount;

    psContext->indent = 0;

    if(language == LANG_DEFAULT)
    {
        language = ChooseLanguage(psShader);
        *planguage = language;
    }

    glsl = bfromcstralloc (1024, GetVersionString(language));

    psContext->glsl = glsl;
	psContext->earlyMain = bfromcstralloc (1024, "");
    for(i=0; i<NUM_PHASES;++i)
    {
        psContext->postShaderCode[i] = bfromcstralloc (1024, "");
    }
    psContext->currentGLSLString = &glsl;
    psShader->eTargetLanguage = language;
	psShader->extensions = (const struct GlExtensions*)extensions;
    psContext->currentPhase = MAIN_PHASE;

	if(extensions)
	{
		if(extensions->ARB_explicit_attrib_location)
			bcatcstr(glsl,"#extension GL_ARB_explicit_attrib_location : require\n");
		if(extensions->ARB_explicit_uniform_location)
			bcatcstr(glsl,"#extension GL_ARB_explicit_uniform_location : require\n");
		if(extensions->ARB_shading_language_420pack)
			bcatcstr(glsl,"#extension GL_ARB_shading_language_420pack : require\n");
	}

    ClearDependencyData(psShader->eShaderType, psContext->psDependencies);

    AddVersionDependentCode(psContext);

    if(psContext->flags & HLSLCC_FLAG_UNIFORM_BUFFER_OBJECT)
    {
        bcatcstr(glsl, "layout(std140) uniform;\n");
    }

    //Special case. Can have multiple phases.
    if(psShader->eShaderType == HULL_SHADER)
    {
        int haveInstancedForkPhase = 0;
        uint32_t forkIndex = 0;

        ConsolidateHullTempVars(psShader);

        for(i=0; i < psShader->ui32HSDeclCount; ++i)
        {
            TranslateDeclaration(psContext, psShader->psHSDecl+i);
        }

        //control
        psContext->currentPhase = HS_CTRL_POINT_PHASE;

        if(psShader->ui32HSControlPointDeclCount)
        {
            bcatcstr(glsl, "//Control point phase declarations\n");
            for(i=0; i < psShader->ui32HSControlPointDeclCount; ++i)
            {
                TranslateDeclaration(psContext, psShader->psHSControlPointPhaseDecl+i);
            }
        }

        if(psShader->ui32HSControlPointInstrCount)
        {
			SetDataTypes(psContext, psShader->psHSControlPointPhaseInstr, psShader->ui32HSControlPointInstrCount);

            bcatcstr(glsl, "void control_point_phase()\n{\n");
            psContext->indent++;

                for(i=0; i < psShader->ui32HSControlPointInstrCount; ++i)
                {
                    TranslateInstruction(psContext, psShader->psHSControlPointPhaseInstr+i);
                }
            psContext->indent--;
            bcatcstr(glsl, "}\n");
        }

        //fork
        psContext->currentPhase = HS_FORK_PHASE;
        for(forkIndex = 0; forkIndex < psShader->ui32ForkPhaseCount; ++forkIndex)
        {
            bcatcstr(glsl, "//Fork phase declarations\n");
            for(i=0; i < psShader->aui32HSForkDeclCount[forkIndex]; ++i)
            {
                TranslateDeclaration(psContext, psShader->apsHSForkPhaseDecl[forkIndex]+i);
                if(psShader->apsHSForkPhaseDecl[forkIndex][i].eOpcode == OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT)
                {
                    haveInstancedForkPhase = 1;
                }
            }

            bformata(glsl, "void fork_phase%d()\n{\n", forkIndex);
            psContext->indent++;

			SetDataTypes(psContext, psShader->apsHSForkPhaseInstr[forkIndex], psShader->aui32HSForkInstrCount[forkIndex]-1);

                if(haveInstancedForkPhase)
                {
                    AddIndentation(psContext);
                    bformata(glsl, "for(int forkInstanceID = 0; forkInstanceID < HullPhase%dInstanceCount; ++forkInstanceID) {\n", forkIndex);
                    psContext->indent++;
                }

                    //The minus one here is remove the return statement at end of phases.
                    //This is needed otherwise the for loop will only run once.
                    ASSERT(psShader->apsHSForkPhaseInstr[forkIndex][psShader->aui32HSForkInstrCount[forkIndex]-1].eOpcode == OPCODE_RET);
                    for(i=0; i < psShader->aui32HSForkInstrCount[forkIndex]-1; ++i)
                    {
                        TranslateInstruction(psContext, psShader->apsHSForkPhaseInstr[forkIndex]+i);
                    }

                if(haveInstancedForkPhase)
                {
                    psContext->indent--;
                    AddIndentation(psContext);
                    bcatcstr(glsl, "}\n");

                    if(psContext->havePostShaderCode[psContext->currentPhase])
                    {
#ifdef _DEBUG
                        AddIndentation(psContext);
                        bcatcstr(glsl, "//--- Post shader code ---\n");
#endif
                        bconcat(glsl, psContext->postShaderCode[psContext->currentPhase]);
#ifdef _DEBUG
                        AddIndentation(psContext);
                        bcatcstr(glsl, "//--- End post shader code ---\n");
#endif
                    }
                }

            psContext->indent--;
            bcatcstr(glsl, "}\n");
        }


        //join
        psContext->currentPhase = HS_JOIN_PHASE;
        if(psShader->ui32HSJoinDeclCount)
        {
            bcatcstr(glsl, "//Join phase declarations\n");
            for(i=0; i < psShader->ui32HSJoinDeclCount; ++i)
            {
                TranslateDeclaration(psContext, psShader->psHSJoinPhaseDecl+i);
            }
        }

        if(psShader->ui32HSJoinInstrCount)
        {
			SetDataTypes(psContext, psShader->psHSJoinPhaseInstr, psShader->ui32HSJoinInstrCount);

            bcatcstr(glsl, "void join_phase()\n{\n");
            psContext->indent++;

                for(i=0; i < psShader->ui32HSJoinInstrCount; ++i)
                {
                    TranslateInstruction(psContext, psShader->psHSJoinPhaseInstr+i);
                }

            psContext->indent--;
            bcatcstr(glsl, "}\n");
        }

        bcatcstr(glsl, "void main()\n{\n");

            psContext->indent++;

#ifdef _DEBUG
            AddIndentation(psContext);
            bcatcstr(glsl, "//--- Start Early Main ---\n");
#endif
            bconcat(glsl, psContext->earlyMain);
#ifdef _DEBUG
            AddIndentation(psContext);
            bcatcstr(glsl, "//--- End Early Main ---\n");
#endif

            if(psShader->ui32HSControlPointInstrCount)
            {
                AddIndentation(psContext);
                bcatcstr(glsl, "control_point_phase();\n");

                if(psShader->ui32ForkPhaseCount || psShader->ui32HSJoinInstrCount)
                {
                    AddIndentation(psContext);
                    bcatcstr(glsl, "barrier();\n");
                }
            }
            for(forkIndex = 0; forkIndex < psShader->ui32ForkPhaseCount; ++forkIndex)
            {
                AddIndentation(psContext);
                bformata(glsl, "fork_phase%d();\n", forkIndex);

                if(psShader->ui32HSJoinInstrCount || (forkIndex+1 < psShader->ui32ForkPhaseCount))
                {
                    AddIndentation(psContext);
                    bcatcstr(glsl, "barrier();\n");
                }
            }
            if(psShader->ui32HSJoinInstrCount)
            {
                AddIndentation(psContext);
                bcatcstr(glsl, "join_phase();\n");
            }

            psContext->indent--;

        bcatcstr(glsl, "}\n");

        if(psContext->psDependencies)
        {
            //Save partitioning and primitive type for use by domain shader.
            psContext->psDependencies->eTessOutPrim = psShader->sInfo.eTessOutPrim;

            psContext->psDependencies->eTessPartitioning = psShader->sInfo.eTessPartitioning;
        }

        return;
    }

    if(psShader->eShaderType == DOMAIN_SHADER && psContext->psDependencies)
    {
        //Load partitioning and primitive type from hull shader.
        switch(psContext->psDependencies->eTessOutPrim)
        {
            case TESSELLATOR_OUTPUT_TRIANGLE_CW:
            {
                bcatcstr(glsl, "layout(cw) in;\n");
                break;
            }
            case TESSELLATOR_OUTPUT_POINT:
            {
                bcatcstr(glsl, "layout(point_mode) in;\n");
                break;
            }
            default:
            {
                break;
            }
        }

        switch(psContext->psDependencies->eTessPartitioning)
        {
            case TESSELLATOR_PARTITIONING_FRACTIONAL_ODD:
            {
                bcatcstr(glsl, "layout(fractional_odd_spacing) in;\n");
                break;
            }
            case TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN:
            {
                bcatcstr(glsl, "layout(fractional_even_spacing) in;\n");
                break;
            }
            default:
            {
                break;
            }
        }
    }

    for(i=0; i < ui32DeclCount; ++i)
    {
        TranslateDeclaration(psContext, psShader->psDecl+i);
    }

    bcatcstr(glsl, "void main()\n{\n");

    psContext->indent++;

#ifdef _DEBUG
    AddIndentation(psContext);
    bcatcstr(glsl, "//--- Start Early Main ---\n");
#endif
	bconcat(glsl, psContext->earlyMain);
#ifdef _DEBUG
    AddIndentation(psContext);
    bcatcstr(glsl, "//--- End Early Main ---\n");
#endif

    MarkIntegerImmediates(psContext);

	SetDataTypes(psContext, psShader->psInst, ui32InstCount);

    for(i=0; i < ui32InstCount; ++i)
    {
        TranslateInstruction(psContext, psShader->psInst+i);
    }

    psContext->indent--;

    bcatcstr(glsl, "}\n");
}
Exemplo n.º 2
0
void TranslateToGLSL(HLSLCrossCompilerContext* psContext, GLLang* planguage,const GlExtensions *extensions)
{
    bstring glsl;
    uint32_t i;
    Shader* psShader = psContext->psShader;
    GLLang language = *planguage;
	uint32_t ui32InstCount = 0;
	uint32_t ui32DeclCount = 0;

    psContext->indent = 0;

	/*psShader->sPhase[MAIN_PHASE].ui32InstanceCount = 1;
	psShader->sPhase[MAIN_PHASE].ppsDecl = hlslcc_malloc(sizeof(Declaration*));
	psShader->sPhase[MAIN_PHASE].ppsInst = hlslcc_malloc(sizeof(Instruction*));
	psShader->sPhase[MAIN_PHASE].pui32DeclCount = hlslcc_malloc(sizeof(uint32_t));
	psShader->sPhase[MAIN_PHASE].pui32InstCount = hlslcc_malloc(sizeof(uint32_t));*/

    if(language == LANG_DEFAULT)
    {
        language = ChooseLanguage(psShader);
        *planguage = language;
    }

		glsl = bfromcstralloc (1024, GetVersionString(language));

    psContext->glsl = glsl;
	psContext->earlyMain = bfromcstralloc (1024, "");
    for(i=0; i<NUM_PHASES;++i)
    {
        psContext->postShaderCode[i] = bfromcstralloc (1024, "");
    }
    psContext->currentGLSLString = &glsl;
    psShader->eTargetLanguage = language;
	psShader->extensions = (const struct GlExtensions*)extensions;
    psContext->currentPhase = MAIN_PHASE;

	if(extensions)
	{
		if(extensions->ARB_explicit_attrib_location)
			bcatcstr(glsl,"#extension GL_ARB_explicit_attrib_location : require\n");
		if(extensions->ARB_explicit_uniform_location)
			bcatcstr(glsl,"#extension GL_ARB_explicit_uniform_location : require\n");
		if(extensions->ARB_shading_language_420pack)
			bcatcstr(glsl,"#extension GL_ARB_shading_language_420pack : require\n");
	}

    ClearDependencyData(psShader->eShaderType, psContext->psDependencies);

    AddVersionDependentCode(psContext);

    if(psContext->flags & HLSLCC_FLAG_UNIFORM_BUFFER_OBJECT)
    {
        bcatcstr(glsl, "layout(std140) uniform;\n");
    }

    //Special case. Can have multiple phases.
    if(psShader->eShaderType == HULL_SHADER)
    {
        int haveInstancedForkPhase = 0;			// Do we have an instanced fork phase?
        int isCurrentForkPhasedInstanced = 0;	// Is the current fork phase instanced?
		const char* asPhaseFuncNames[NUM_PHASES];
		uint32_t ui32PhaseFuncCallOrder[3];
		uint32_t ui32PhaseCallIndex;

		uint32_t ui32Phase;
		uint32_t ui32Instance;

		asPhaseFuncNames[MAIN_PHASE] = "";
		asPhaseFuncNames[HS_GLOBAL_DECL] = "";
		asPhaseFuncNames[HS_FORK_PHASE] = "fork_phase";
		asPhaseFuncNames[HS_CTRL_POINT_PHASE] = "control_point_phase";
		asPhaseFuncNames[HS_JOIN_PHASE] = "join_phase";

        ConsolidateHullTempVars(psShader);

		for(i=0; i < psShader->asPhase[HS_GLOBAL_DECL].pui32DeclCount[0]; ++i)
        {
			TranslateDeclaration(psContext, psShader->asPhase[HS_GLOBAL_DECL].ppsDecl[0]+i);
        }

		for(ui32Phase=HS_CTRL_POINT_PHASE; ui32Phase<NUM_PHASES; ui32Phase++)
		{
			psContext->currentPhase = ui32Phase;
			for(ui32Instance = 0; ui32Instance < psShader->asPhase[ui32Phase].ui32InstanceCount; ++ui32Instance)
			{
				isCurrentForkPhasedInstanced = 0; //reset for each fork phase for cases we don't have a fork phase instance count opcode.
				bformata(glsl, "//%s declarations\n", asPhaseFuncNames[ui32Phase]);
				for(i=0; i < psShader->asPhase[ui32Phase].pui32DeclCount[ui32Instance]; ++i)
				{
					TranslateDeclaration(psContext, psShader->asPhase[ui32Phase].ppsDecl[ui32Instance]+i);
					if(psShader->asPhase[ui32Phase].ppsDecl[ui32Instance][i].eOpcode == OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT)
					{
						haveInstancedForkPhase = 1;
						isCurrentForkPhasedInstanced = 1;
					}
				}

				bformata(glsl, "void %s%d()\n{\n", asPhaseFuncNames[ui32Phase], ui32Instance);
				psContext->indent++;

				SetDataTypes(psContext, psShader->asPhase[ui32Phase].ppsInst[ui32Instance], psShader->asPhase[ui32Phase].pui32InstCount[ui32Instance]-1);

					if(isCurrentForkPhasedInstanced)
					{
						AddIndentation(psContext);
						bformata(glsl, "for(int forkInstanceID = 0; forkInstanceID < HullPhase%dInstanceCount; ++forkInstanceID) {\n", ui32Instance);
						psContext->indent++;
					}

						//The minus one here is remove the return statement at end of phases.
						//This is needed otherwise the for loop will only run once.
						ASSERT(psShader->asPhase[ui32Phase].ppsInst[ui32Instance]  [psShader->asPhase[ui32Phase].pui32InstCount[ui32Instance]-1].eOpcode == OPCODE_RET);
						for(i=0; i < psShader->asPhase[ui32Phase].pui32InstCount[ui32Instance]-1; ++i)
						{
							TranslateInstruction(psContext, psShader->asPhase[ui32Phase].ppsInst[ui32Instance]+i, NULL);
						}

					if(haveInstancedForkPhase)
					{
						psContext->indent--;
						AddIndentation(psContext);

						if(isCurrentForkPhasedInstanced)
						{
							bcatcstr(glsl, "}\n");
						}

						if(psContext->havePostShaderCode[psContext->currentPhase])
						{
	#ifdef _DEBUG
							AddIndentation(psContext);
							bcatcstr(glsl, "//--- Post shader code ---\n");
	#endif
							bconcat(glsl, psContext->postShaderCode[psContext->currentPhase]);
	#ifdef _DEBUG
							AddIndentation(psContext);
							bcatcstr(glsl, "//--- End post shader code ---\n");
	#endif
						}
				}

				psContext->indent--;
				bcatcstr(glsl, "}\n");
			}
		}

        bcatcstr(glsl, "void main()\n{\n");

            psContext->indent++;

#ifdef _DEBUG
            AddIndentation(psContext);
            bcatcstr(glsl, "//--- Start Early Main ---\n");
#endif
            bconcat(glsl, psContext->earlyMain);
#ifdef _DEBUG
            AddIndentation(psContext);
            bcatcstr(glsl, "//--- End Early Main ---\n");
#endif

			ui32PhaseFuncCallOrder[0] = HS_CTRL_POINT_PHASE;
			ui32PhaseFuncCallOrder[1] = HS_FORK_PHASE;
			ui32PhaseFuncCallOrder[2] = HS_JOIN_PHASE;

			for(ui32PhaseCallIndex=0; ui32PhaseCallIndex<3; ui32PhaseCallIndex++)
			{
				ui32Phase = ui32PhaseFuncCallOrder[ui32PhaseCallIndex];
				for(ui32Instance = 0; ui32Instance < psShader->asPhase[ui32Phase].ui32InstanceCount; ++ui32Instance)
				{
					AddIndentation(psContext);
					bformata(glsl, "%s%d();\n", asPhaseFuncNames[ui32Phase], ui32Instance);

					if(ui32Phase == HS_FORK_PHASE)
					{
						if(psShader->asPhase[HS_JOIN_PHASE].ui32InstanceCount ||
							(ui32Instance+1 < psShader->asPhase[HS_FORK_PHASE].ui32InstanceCount))
						{
							AddIndentation(psContext);
							bcatcstr(glsl, "barrier();\n");
						}
					}
				}
			}

            psContext->indent--;

        bcatcstr(glsl, "}\n");

        if(psContext->psDependencies)
        {
            //Save partitioning and primitive type for use by domain shader.
            psContext->psDependencies->eTessOutPrim = psShader->sInfo.eTessOutPrim;

            psContext->psDependencies->eTessPartitioning = psShader->sInfo.eTessPartitioning;
        }

        return;
    }

    if(psShader->eShaderType == DOMAIN_SHADER && psContext->psDependencies)
    {
        //Load partitioning and primitive type from hull shader.
        switch(psContext->psDependencies->eTessOutPrim)
        {
            case TESSELLATOR_OUTPUT_TRIANGLE_CW:
            {
                bcatcstr(glsl, "layout(cw) in;\n");
                break;
            }
            case TESSELLATOR_OUTPUT_POINT:
            {
                bcatcstr(glsl, "layout(point_mode) in;\n");
                break;
            }
            default:
            {
                break;
            }
        }

        switch(psContext->psDependencies->eTessPartitioning)
        {
            case TESSELLATOR_PARTITIONING_FRACTIONAL_ODD:
            {
                bcatcstr(glsl, "layout(fractional_odd_spacing) in;\n");
                break;
            }
            case TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN:
            {
                bcatcstr(glsl, "layout(fractional_even_spacing) in;\n");
                break;
            }
            default:
            {
                break;
            }
        }
    }

	ui32InstCount = psShader->asPhase[MAIN_PHASE].pui32InstCount[0];
	ui32DeclCount = psShader->asPhase[MAIN_PHASE].pui32DeclCount[0];

    for(i=0; i < ui32DeclCount; ++i)
    {
		TranslateDeclaration(psContext, psShader->asPhase[MAIN_PHASE].ppsDecl[0]+i);
    }

	if(psContext->psShader->ui32NumDx9ImmConst)
	{
		bformata(psContext->glsl, "vec4 ImmConstArray [%d];\n", psContext->psShader->ui32NumDx9ImmConst);
	}

    bcatcstr(glsl, "void main()\n{\n");

    psContext->indent++;

#ifdef _DEBUG
    AddIndentation(psContext);
    bcatcstr(glsl, "//--- Start Early Main ---\n");
#endif
	bconcat(glsl, psContext->earlyMain);
#ifdef _DEBUG
    AddIndentation(psContext);
    bcatcstr(glsl, "//--- End Early Main ---\n");
#endif

    MarkIntegerImmediates(psContext);

	SetDataTypes(psContext, psShader->asPhase[MAIN_PHASE].ppsInst[0], ui32InstCount);

    for(i=0; i < ui32InstCount; ++i)
    {
		TranslateInstruction(psContext, psShader->asPhase[MAIN_PHASE].ppsInst[0]+i, i+1 < ui32InstCount ? psShader->asPhase[MAIN_PHASE].ppsInst[0]+i+1 : 0);
    }

    psContext->indent--;

    bcatcstr(glsl, "}\n");
}