Exemple #1
0
/* Returns true if the parsing covered the whole input. */
bool ParseFirstPart()
{
	char *entryOrExternStart;

	if (NULL == part)
		return true;
	/* check for comment, assuming that a commented line must starts with a comment char */
	if (strchr(part, COMMENT_CHAR) == part)
		return true;
	/* check for label */
	if (ValidateLabel(part, LABEL_END_CHAR, true, true, labelName) > ZERO && labelName != NULL)
	{
		isLabel = true;
		return false;
	}
	else if (strstr(part, DATA_DEFINITION) != NULL)
	{ /* data array without a label */
		ParseDataArray();
		return true;
	}
	else if (strstr(part, STRING_DEFINITION) != NULL)
	{ /* string definition without a label */
		ParseStringDefinition();
		return true;
	}
	/* TODO: deal with .entry and .extern - NO LABEL ALLOWED PRIOR ! ! ! */
	else if ((entryOrExternStart = strstr(part, EXTERN_DEFINITION)) != NULL)
	{
		if (!AddEntryOrExtern(false, entryOrExternStart))
			return false;
		return true;
	}
	else if ((entryOrExternStart = strstr(part, ENTRY_DEFINITION)) != NULL)
	{
		if (!AddEntryOrExtern(true, entryOrExternStart))
			return false;
		return true;
	}
	else if (!TranslateInstruction())
	{
		char *lastError = GetLastError();

		SYNTAX_ASSERT(strcmp(lastError, EMPTY_STRING) == ZERO, lastError);
		SetLastError(EMPTY_STRING);
		return false;
	}
	return true;
}
Exemple #2
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");
}
Exemple #3
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");
}
Exemple #4
0
bool ParseLine(char * inputLine)
{
	size_t originalDC;

	/* setup */
	isLabel = false;
	memset(word, 0, sizeof(word_type));
	memset(view, 0, sizeof(word_view_type));
	memset(labelName, 0, MAX_LABEL_LENGTH);

	strncpy(line, inputLine, MAX_LINE_LENGTH);
	strncpy(lineCopy, inputLine, MAX_LINE_LENGTH);

#ifdef VERBOSE
	printf("Parsing '%s'\n", inputLine);
#endif

	/* split the line into part */
	part = strtok(lineCopy, IGNORED_DELIMITERS);
	if (ParseFirstPart())
		return true;
	else if (localSyntaxError)
		return false;
	/* continue iterating over the split'd part */
	if (NULL == (part = strtok(NULL, IGNORED_DELIMITERS)))
	{
		SYNTAX_ASSERT(false, NOT_EXPECTING_EOL);
		return false;
	}

	originalDC = DC;
	if (strstr(part, DATA_DEFINITION) != NULL)
	{ /* data array */
		if (!isLabel)
		{
			SYNTAX_ASSERT(false, DATA_DEF_REDUNDANT);
			return false;
		}
		/* construct a word-per-element of the array and store it */
		if (ERROR != ParseDataArray())
			AddLabel(labelName, originalDC, true);
		return false;
	}
	else if (strstr(part, STRING_DEFINITION) != NULL)
	{ /* string definition */
		if (!isLabel)
		{
			SYNTAX_ASSERT(false, STRING_DEF_REDUNDANT);
			return false;
		}
		/* construct a word-per-character of the string and store it */
		if (ERROR != ParseStringDefinition())
			AddLabel(labelName, originalDC, true);
		return false;
	}
	else
	{	/* instruction */
		if (isLabel)
			AddLabel(labelName, ZERO, false);
		if (!TranslateInstruction())
			return false;
	}
	return true;
}