Exemplo n.º 1
0
static void TranslateVariableName(HLSLCrossCompilerContext* psContext, const Operand* psOperand, uint32_t ui32TOFlag, uint32_t* pui32IgnoreSwizzle)
{
    int integerConstructor = 0;
    bstring glsl = *psContext->currentGLSLString;

    *pui32IgnoreSwizzle = 0;

    if(psOperand->eType != OPERAND_TYPE_IMMEDIATE32 &&
        psOperand->eType != OPERAND_TYPE_IMMEDIATE64 &&
        psOperand->eType != OPERAND_TYPE_CONSTANT_BUFFER)
    {
		const uint32_t swizCount = psOperand->iNumComponents;
		SHADER_VARIABLE_TYPE eType = GetOperandDataType(psContext, psOperand);

		if( (ui32TOFlag & (TO_FLAG_INTEGER|TO_FLAG_UNSIGNED_INTEGER)) == (TO_FLAG_INTEGER|TO_FLAG_UNSIGNED_INTEGER))
		{
			//Can be either int or uint
			if(eType != SVT_INT && eType != SVT_UINT)
			{
				if(swizCount == 1)
					bformata(glsl, "int(");
				else
					bformata(glsl, "ivec%d(", swizCount);

				integerConstructor = 1;
			}
		}
		else
		{
			if((ui32TOFlag & (TO_FLAG_INTEGER|TO_FLAG_DESTINATION))==TO_FLAG_INTEGER &&
				eType != SVT_INT)
			{
				//Convert to int
				if(swizCount == 1)
					bformata(glsl, "int(");
				else
					bformata(glsl, "ivec%d(", swizCount);

				integerConstructor = 1;
			}
			if((ui32TOFlag & (TO_FLAG_UNSIGNED_INTEGER|TO_FLAG_DESTINATION))==TO_FLAG_UNSIGNED_INTEGER &&
				eType != SVT_UINT)
			{
				//Convert to uint
				if(swizCount == 1)
					bformata(glsl, "uint(");
				else
					bformata(glsl, "uvec%d(", swizCount);
				integerConstructor = 1;
			}
		}
    }

    switch(psOperand->eType)
    {
        case OPERAND_TYPE_IMMEDIATE32:
        {
            if(psOperand->iNumComponents == 1)
            {
				if(ui32TOFlag & TO_FLAG_UNSIGNED_INTEGER)
				{
					bformata(glsl, "%uu",
						*((unsigned int*)(&psOperand->afImmediates[0])));
				}
                else
				if((ui32TOFlag & TO_FLAG_INTEGER) || psOperand->iIntegerImmediate || fpcheck(psOperand->afImmediates[0]))
				{
					bformata(glsl, "%d",
						*((int*)(&psOperand->afImmediates[0])));
				}
				else
				{
					bformata(glsl, "%f",
                    psOperand->afImmediates[0]);
				}
            }
            else
            {
                if(ui32TOFlag & TO_FLAG_UNSIGNED_INTEGER)
                {
                    bformata(glsl, "uvec4(%uu, %uu, %uu, %uu)",
                        *(unsigned int*)&psOperand->afImmediates[0],
                        *(unsigned int*)&psOperand->afImmediates[1],
                        *(unsigned int*)&psOperand->afImmediates[2],
                        *(unsigned int*)&psOperand->afImmediates[3]);
                }
                else
                if((ui32TOFlag & TO_FLAG_INTEGER) ||
                    psOperand->iIntegerImmediate ||
                    fpcheck(psOperand->afImmediates[0]) ||
                    fpcheck(psOperand->afImmediates[1]) ||
                    fpcheck(psOperand->afImmediates[2]) ||
                    fpcheck(psOperand->afImmediates[3]))
                {
                    bformata(glsl, "ivec4(%d, %d, %d, %d)",
                        *(int*)&psOperand->afImmediates[0],
                        *(int*)&psOperand->afImmediates[1],
                        *(int*)&psOperand->afImmediates[2],
                        *(int*)&psOperand->afImmediates[3]);
                }
                else
                {
                    bformata(glsl, "vec4(%f, %f, %f, %f)",
                        psOperand->afImmediates[0],
                        psOperand->afImmediates[1],
                        psOperand->afImmediates[2],
                        psOperand->afImmediates[3]);
                }
                if(psOperand->iNumComponents != 4)
                {
                    AddSwizzleUsingElementCount(psContext, psOperand->iNumComponents);
                }
            }
            break;
        }
        case OPERAND_TYPE_IMMEDIATE64:
        {
            if(psOperand->iNumComponents == 1)
            {
                bformata(glsl, "%f",
                    psOperand->adImmediates[0]);
            }
            else
            {
                bformata(glsl, "dvec4(%f, %f, %f, %f)",
                    psOperand->adImmediates[0],
                    psOperand->adImmediates[1],
                    psOperand->adImmediates[2],
                    psOperand->adImmediates[3]);
                if(psOperand->iNumComponents != 4)
                {
                    AddSwizzleUsingElementCount(psContext, psOperand->iNumComponents);
                }
            }
            break;
        }
        case OPERAND_TYPE_INPUT:
        {
            switch(psOperand->iIndexDims)
            {
                case INDEX_2D:
                {
                    if(psOperand->aui32ArraySizes[1] == 0)//Input index zero - position.
                    {
                        bcatcstr(glsl, "gl_in");
                        TranslateOperandIndex(psContext, psOperand, TO_FLAG_NONE);//Vertex index
                        bcatcstr(glsl, ".gl_Position");
                    }
                    else
                    {
                        const char* name = "Input";
                        if(ui32TOFlag & TO_FLAG_DECLARATION_NAME)
                        {
                            name = GetDeclaredInputName(psContext, psContext->psShader->eShaderType, psOperand);
                        }
                        
                        bformata(glsl, "%s%d", name, psOperand->aui32ArraySizes[1]);
                        TranslateOperandIndex(psContext, psOperand, TO_FLAG_NONE);//Vertex index
                    }
                    break;
                }
                default:
                {
                    if(psOperand->eIndexRep[0] == OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE)
                    {
                        bformata(glsl, "Input%d[int(", psOperand->ui32RegisterNumber);
                        TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE);
                        bcatcstr(glsl, ")]");
                    }
                    else
                    {
                        if(psContext->psShader->aIndexedInput[psOperand->ui32RegisterNumber] != 0)
                        {
                            const uint32_t parentIndex = psContext->psShader->aIndexedInputParents[psOperand->ui32RegisterNumber];
                            bformata(glsl, "Input%d[%d]", parentIndex,
                                psOperand->ui32RegisterNumber - parentIndex);
                        }
                        else
                        {
                            if(ui32TOFlag & TO_FLAG_DECLARATION_NAME)
                            {
                                const char* name = GetDeclaredInputName(psContext, psContext->psShader->eShaderType, psOperand);
								bcatcstr(glsl, name);
                            }
							else
							{
								bformata(glsl, "Input%d", psOperand->ui32RegisterNumber);
							}
                        }
                    }
                    break;
                }
            }
            break;
        }
        case OPERAND_TYPE_OUTPUT:
        {
            bformata(glsl, "Output%d", psOperand->ui32RegisterNumber);
            if(psOperand->psSubOperand[0])
            {
                bcatcstr(glsl, "[int("); //Indexes must be integral.
                TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE);
                bcatcstr(glsl, ")]");
            }
            break;
        }
        case OPERAND_TYPE_OUTPUT_DEPTH:
        case OPERAND_TYPE_OUTPUT_DEPTH_GREATER_EQUAL:
        case OPERAND_TYPE_OUTPUT_DEPTH_LESS_EQUAL:
        {
            bcatcstr(glsl, "gl_FragDepth");
            break;
        }
        case OPERAND_TYPE_TEMP:
        {
			SHADER_VARIABLE_TYPE eType = GetOperandDataType(psContext, psOperand);
            bcatcstr(glsl, "Temp");

            if(eType == SVT_INT)
            {
                bcatcstr(glsl, "_int");
            }
            else if(eType == SVT_UINT)
            {
                bcatcstr(glsl, "_uint");
            }
			else if(eType == SVT_DOUBLE)
			{
				bcatcstr(glsl, "_double");
			}
            else if(eType == SVT_VOID ||
                (ui32TOFlag & TO_FLAG_DESTINATION))
            {
                if(ui32TOFlag & TO_FLAG_INTEGER)
                {
                    bcatcstr(glsl, "_int");
                }
                else
                if(ui32TOFlag & TO_FLAG_UNSIGNED_INTEGER)
                {
                    bcatcstr(glsl, "_uint");
                }
            }

			bformata(glsl, "[%d]", psOperand->ui32RegisterNumber);

            break;
        }
		case OPERAND_TYPE_SPECIAL_IMMCONSTINT:
		{
            bformata(glsl, "IntImmConst%d", psOperand->ui32RegisterNumber);
            break;
		}
        case OPERAND_TYPE_SPECIAL_IMMCONST:
        {
            bformata(glsl, "ImmConst%d", psOperand->ui32RegisterNumber);
            break;
        }
        case OPERAND_TYPE_SPECIAL_OUTBASECOLOUR:
        {
            bcatcstr(glsl, "BaseColour");
            break;
        }
        case OPERAND_TYPE_SPECIAL_OUTOFFSETCOLOUR:
        {
            bcatcstr(glsl, "OffsetColour");
            break;
        }
        case OPERAND_TYPE_SPECIAL_POSITION:
        {
            bcatcstr(glsl, "gl_Position");
            break;
        }
        case OPERAND_TYPE_SPECIAL_FOG:
        {
            bcatcstr(glsl, "Fog");
            break;
        }
        case OPERAND_TYPE_SPECIAL_POINTSIZE:
        {
            bcatcstr(glsl, "gl_PointSize");
            break;
        }
        case OPERAND_TYPE_SPECIAL_ADDRESS:
        {
            bcatcstr(glsl, "Address");
            break;
        }
		case OPERAND_TYPE_SPECIAL_TEXCOORD:
		{
			bformata(glsl, "TexCoord%d", psOperand->ui32RegisterNumber);
			break;
		}
        case OPERAND_TYPE_CONSTANT_BUFFER:
        {
            const char* StageName = "VS";
            ConstantBuffer* psCBuf = NULL;
            ShaderVarType* psVarType = NULL;
            int32_t index = -1;
            GetConstantBufferFromBindingPoint(RGROUP_CBUFFER, psOperand->aui32ArraySizes[0], &psContext->psShader->sInfo, &psCBuf);

            switch(psContext->psShader->eShaderType)
            {
                case PIXEL_SHADER:
                {
                    StageName = "PS";
                    break;
                }
                case HULL_SHADER:
                {
                    StageName = "HS";
                    break;
                }
                case DOMAIN_SHADER:
                {
                    StageName = "DS";
                    break;
                }
                case GEOMETRY_SHADER:
                {
                    StageName = "GS";
                    break;
                }
				case COMPUTE_SHADER:
				{
					StageName = "CS";
					break;
				}
                default:
                {
                    break;
                }
            }

            if(ui32TOFlag & TO_FLAG_DECLARATION_NAME)
            {
                pui32IgnoreSwizzle[0] = 1;
            }

			if((psContext->flags & HLSLCC_FLAG_UNIFORM_BUFFER_OBJECT)!=HLSLCC_FLAG_UNIFORM_BUFFER_OBJECT)
			{
				if(psCBuf)
				{
					//$Globals.
					if(psCBuf->Name[0] == '$')
					{
						bformata(glsl, "Globals%s", StageName);
					}
					else
					{
						bformata(glsl, "%s%s", psCBuf->Name, StageName);
					}
					if((ui32TOFlag & TO_FLAG_DECLARATION_NAME) != TO_FLAG_DECLARATION_NAME)
					{
						bcatcstr(glsl, ".");
					}
				}
				else
				{
					//bformata(glsl, "cb%d", psOperand->aui32ArraySizes[0]);
				}
		}

            if((ui32TOFlag & TO_FLAG_DECLARATION_NAME) != TO_FLAG_DECLARATION_NAME)
            {
                //Work out the variable name. Don't apply swizzle to that variable yet.
				int32_t rebase = 0;

				if(psCBuf)
				{
					GetShaderVarFromOffset(psOperand->aui32ArraySizes[1], psOperand->aui32Swizzle, psCBuf, &psVarType, &index, &rebase);

					bformata(glsl, "%s", psVarType->FullName);
				}
				else // We don't have a semantic for this variable, so try the raw dump appoach.
				{
					bformata(glsl, "cb%d.data", psOperand->aui32ArraySizes[0]);//
					index = psOperand->aui32ArraySizes[1];
				}

				//Dx9 only?
				if(psOperand->psSubOperand[0] != NULL)
				{
					SHADER_VARIABLE_TYPE eType = GetOperandDataType(psContext, psOperand->psSubOperand[0]);
					if(eType != SVT_INT && eType != SVT_UINT)
					{
						bcatcstr(glsl, "[int("); //Indexes must be integral.
						TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE);
						bcatcstr(glsl, ")]");
					}
					else
					{
						bcatcstr(glsl, "["); //Indexes must be integral.
						TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE);
						bcatcstr(glsl, "]");
					}

					ASSERT(index == 0 || index == -1);
				}
				else
				if(index != -1 && psOperand->psSubOperand[1] != NULL)
				{
					//Array of matrices is treated as array of vec4s
					if(index != -1)
					{
						SHADER_VARIABLE_TYPE eType = GetOperandDataType(psContext, psOperand->psSubOperand[1]);
						if(eType != SVT_INT && eType != SVT_UINT)
						{
							bcatcstr(glsl, "[int(");
							TranslateOperand(psContext, psOperand->psSubOperand[1], TO_FLAG_NONE);
							bformata(glsl, ") + %d]", index);
						}
						else
						{
							bcatcstr(glsl, "[");
							TranslateOperand(psContext, psOperand->psSubOperand[1], TO_FLAG_NONE);
							bformata(glsl, " + %d]", index);
						}
					}
				}
				else if(index != -1)
                {
                    bformata(glsl, "[%d]", index);
                }
				else if(psOperand->psSubOperand[1] != NULL)
				{
					SHADER_VARIABLE_TYPE eType = GetOperandDataType(psContext, psOperand->psSubOperand[1]);
					if(eType != SVT_INT && eType != SVT_UINT)
					{
						bcatcstr(glsl, "[");
						TranslateOperand(psContext, psOperand->psSubOperand[1], TO_FLAG_NONE);
						bcatcstr(glsl, "]");
					}
					else
					{
						bcatcstr(glsl, "[int(");
						TranslateOperand(psContext, psOperand->psSubOperand[1], TO_FLAG_NONE);
						bcatcstr(glsl, ")]");
					}
				}

				if(psVarType && psVarType->Class == SVC_VECTOR)
				{
					switch(rebase)
					{
						case 4:
						{
							if(psVarType->Columns == 2)
							{
								//.x(GLSL) is .y(HLSL). .y(GLSL) is .z(HLSL)
								bcatcstr(glsl, ".xxyx");
							}
							else if(psVarType->Columns == 3)
							{
								//.x(GLSL) is .y(HLSL). .y(GLSL) is .z(HLSL) .z(GLSL) is .w(HLSL)
								bcatcstr(glsl, ".xxyz");
							}
							break;
						}
						case 8:
						{
							if(psVarType->Columns == 2)
							{
								//.x(GLSL) is .z(HLSL). .y(GLSL) is .w(HLSL)
								bcatcstr(glsl, ".xxxy");
							}
							break;
						}
						case 0:
						default:
						{
							//No rebase, but extend to vec4.
							if(psVarType->Columns == 2)
							{
								bcatcstr(glsl, ".xyxx");
							}
							else if(psVarType->Columns == 3)
							{
								bcatcstr(glsl, ".xyzx");
							}
							break;
						}

					}
				}

				if(psVarType && psVarType->Class == SVC_SCALAR)
				{
					*pui32IgnoreSwizzle = 1;
				}
            }
            break;
        }
        case OPERAND_TYPE_RESOURCE:
        {
            TextureName(psContext, psOperand->ui32RegisterNumber, 0);
			*pui32IgnoreSwizzle = 1;
            break;
        }
        case OPERAND_TYPE_SAMPLER:
        {
            bformata(glsl, "Sampler%d", psOperand->ui32RegisterNumber);
			*pui32IgnoreSwizzle = 1;
            break;
        }
        case OPERAND_TYPE_FUNCTION_BODY:
        {
            const uint32_t ui32FuncBody = psOperand->ui32RegisterNumber;
            const uint32_t ui32FuncTable = psContext->psShader->aui32FuncBodyToFuncTable[ui32FuncBody];
            //const uint32_t ui32FuncPointer = psContext->psShader->aui32FuncTableToFuncPointer[ui32FuncTable];
            const uint32_t ui32ClassType = psContext->psShader->sInfo.aui32TableIDToTypeID[ui32FuncTable];
            const char* ClassTypeName = &psContext->psShader->sInfo.psClassTypes[ui32ClassType].Name[0];
            const uint32_t ui32UniqueClassFuncIndex = psContext->psShader->ui32NextClassFuncName[ui32ClassType]++;

            bformata(glsl, "%s_Func%d", ClassTypeName, ui32UniqueClassFuncIndex);
            break;
        }
		case OPERAND_TYPE_INPUT_FORK_INSTANCE_ID:
		{
			bcatcstr(glsl, "forkInstanceID");
            *pui32IgnoreSwizzle = 1;
			return;
		}
		case OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER:
		{
            bcatcstr(glsl, "immediateConstBufferF");

            if(psOperand->psSubOperand[0])
            {
                bcatcstr(glsl, "(int("); //Indexes must be integral.
                TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE);
                bcatcstr(glsl, "))");
            }
			break;
		}
		case OPERAND_TYPE_INPUT_DOMAIN_POINT:
		{
			bcatcstr(glsl, "gl_TessCoord");
			break;
		}
		case OPERAND_TYPE_INPUT_CONTROL_POINT:
		{
			if(psOperand->aui32ArraySizes[1] == 0)//Input index zero - position.
			{
				bformata(glsl, "gl_in[%d].gl_Position", psOperand->aui32ArraySizes[0]);
			}
            else
            {
                bformata(glsl, "Input%d[%d]", psOperand->aui32ArraySizes[1], psOperand->aui32ArraySizes[0]);
            }
            break;
		}
		case OPERAND_TYPE_NULL:
		{
			// Null register, used to discard results of operations
			bcatcstr(glsl, "//null");
			break;
		}
        case OPERAND_TYPE_OUTPUT_CONTROL_POINT_ID:
        {
            bcatcstr(glsl, "gl_InvocationID");
            *pui32IgnoreSwizzle = 1;
            break;
        }
        case OPERAND_TYPE_OUTPUT_COVERAGE_MASK:
        {
            bcatcstr(glsl, "gl_SampleMask[0]");
            *pui32IgnoreSwizzle = 1;
            break;
        }
        case OPERAND_TYPE_INPUT_COVERAGE_MASK:
        {
            bcatcstr(glsl, "gl_SampleMaskIn[0]");
            //Skip swizzle on scalar types.
            *pui32IgnoreSwizzle = 1;
            break;
        }
		case OPERAND_TYPE_INPUT_THREAD_ID://SV_DispatchThreadID
		{
			bcatcstr(glsl, "gl_GlobalInvocationID");
			break;
		}
		case OPERAND_TYPE_INPUT_THREAD_GROUP_ID://SV_GroupThreadID
		{
			bcatcstr(glsl, "gl_LocalInvocationID");
			break;
		}
		case OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP://SV_GroupID
		{
			bcatcstr(glsl, "gl_WorkGroupID");
			break;
		}
		case OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED://SV_GroupIndex
		{
			bcatcstr(glsl, "gl_LocalInvocationIndex");
			break;
		}
        case OPERAND_TYPE_UNORDERED_ACCESS_VIEW:
        {
            bformata(glsl, "UAV%d", psOperand->ui32RegisterNumber);
            break;
        }
        case OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY:
        {
            bformata(glsl, "TGSM%d", psOperand->ui32RegisterNumber);
            break;
        }
		case OPERAND_TYPE_INPUT_PRIMITIVEID:
		{
			bcatcstr(glsl, "gl_PrimitiveID");
			break;
		}
        case OPERAND_TYPE_INDEXABLE_TEMP:
        {
            bformata(glsl, "TempArray%d", psOperand->aui32ArraySizes[0]);
            bformata(glsl, "[%d", psOperand->aui32ArraySizes[1]);
            
            if(psOperand->psSubOperand[1])
            {
                bcatcstr(glsl, "+");
                TranslateOperand(psContext, psOperand->psSubOperand[1], TO_FLAG_NONE);
                
            }
            bcatcstr(glsl, "]");
            break;
        }
		case OPERAND_TYPE_STREAM:
		{
			bformata(glsl, "%d", psOperand->ui32RegisterNumber);
			break;
		}
		case OPERAND_TYPE_INPUT_GS_INSTANCE_ID:
		{
			bcatcstr(glsl, "gl_InvocationID");
			break;
		}
		case OPERAND_TYPE_THIS_POINTER:
		{
			/*
				The "this" register is a register that provides up to 4 pieces of information:
				X: Which CB holds the instance data
				Y: Base element offset of the instance data within the instance CB
				Z: Base sampler index
				W: Base Texture index

				Can be different for each function call
			*/
			break;
		}
        default:
        {
            ASSERT(0);
            break;
        }
    }

    if(integerConstructor)
    {
        bcatcstr(glsl, ")");
    }
}
Exemplo n.º 2
0
SHADER_VARIABLE_TYPE GetOperandDataType(HLSLCrossCompilerContext* psContext, const Operand* psOperand)
{
    switch(psOperand->eType)
	{
		case OPERAND_TYPE_TEMP:
		{
			SHADER_VARIABLE_TYPE eCurrentType;
			int i = 0;

			if(psOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE)
			{
				return psOperand->aeDataType[psOperand->aui32Swizzle[0]];
			}
			if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE)
			{
				if(psOperand->ui32Swizzle == (NO_SWIZZLE))
				{
					return psOperand->aeDataType[0];
				}

				return psOperand->aeDataType[psOperand->aui32Swizzle[0]];
			}

			if(psOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE)
			{
				uint32_t ui32CompMask = psOperand->ui32CompMask;
				if(!psOperand->ui32CompMask)
				{
					ui32CompMask = OPERAND_4_COMPONENT_MASK_ALL;
				}
				for(;i<4;++i)
				{
					if(ui32CompMask & (1<<i))
					{
						eCurrentType = psOperand->aeDataType[i];
						break;
					}
				}

	#ifdef _DEBUG
				//Check if all elements have the same basic type.
				for(;i<4;++i)
				{
					if(psOperand->ui32CompMask & (1<<i))
					{
						if(eCurrentType != psOperand->aeDataType[i])
						{
							ASSERT(0);
						}
					}
				}
	#endif
				return eCurrentType;
			}

			ASSERT(0);
    
			break;
		}
		case OPERAND_TYPE_OUTPUT:
		{
			const uint32_t ui32Register = psOperand->aui32ArraySizes[psOperand->iIndexDims-1];
			InOutSignature* psOut;

			if(GetOutputSignatureFromRegister(ui32Register, psOperand->ui32CompMask, 0, &psContext->psShader->sInfo, &psOut))
			{
				if( psOut->eComponentType == INOUT_COMPONENT_UINT32)
				{
					return SVT_UINT;
				}
				else if( psOut->eComponentType == INOUT_COMPONENT_SINT32)
				{
					return SVT_INT;
				}
			}
			break;
		}
		case OPERAND_TYPE_INPUT:
		{
			const uint32_t ui32Register = psOperand->aui32ArraySizes[psOperand->iIndexDims-1];
			InOutSignature* psIn;

			//UINT in DX, INT in GL.
			if(psOperand->eSpecialName == NAME_PRIMITIVE_ID)
			{
				return SVT_INT;
			}

			if(GetInputSignatureFromRegister(ui32Register, &psContext->psShader->sInfo, &psIn))
			{
				if( psIn->eComponentType == INOUT_COMPONENT_UINT32)
				{
					return SVT_UINT;
				}
				else if( psIn->eComponentType == INOUT_COMPONENT_SINT32)
				{
					return SVT_INT;
				}
			}
			break;
		}
		case OPERAND_TYPE_CONSTANT_BUFFER:
		{
			ConstantBuffer* psCBuf = NULL;
			ShaderVarType* psVarType = NULL;
			int32_t index = -1;
			int32_t rebase = -1;
			int foundVar;
			GetConstantBufferFromBindingPoint(RGROUP_CBUFFER, psOperand->aui32ArraySizes[0], &psContext->psShader->sInfo, &psCBuf);
			if(psCBuf)
			{
				foundVar = GetShaderVarFromOffset(psOperand->aui32ArraySizes[1], psOperand->aui32Swizzle, psCBuf, &psVarType, &index, &rebase);
				if(foundVar && index == -1 && psOperand->psSubOperand[1] == NULL)
				{
					return psVarType->Type;
				}
			}
			else
			{
				// Todo: this isn't correct yet.
				return SVT_FLOAT;
			}
			break;
		}
		case OPERAND_TYPE_IMMEDIATE32:
		{
			return psOperand->iIntegerImmediate ? SVT_INT : SVT_FLOAT;
		}

		case OPERAND_TYPE_INPUT_THREAD_ID:
		case OPERAND_TYPE_INPUT_THREAD_GROUP_ID:
		case OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP:
		case OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED:
		{
			return SVT_UINT;
		}
		case OPERAND_TYPE_SPECIAL_ADDRESS:
		{
			return SVT_INT;
		}
		default:
		{
			return SVT_FLOAT;
		}
	}

	return SVT_FLOAT;
}
Exemplo n.º 3
0
static void TranslateVariableName(HLSLCrossCompilerContext* psContext, const Operand* psOperand, uint32_t ui32TOFlag, uint32_t* pui32IgnoreSwizzle)
{
    bstring glsl = *psContext->currentGLSLString;

    *pui32IgnoreSwizzle = 0;

    switch(psOperand->eType)
    {
        case OPERAND_TYPE_IMMEDIATE32:
        {
            if(psOperand->iNumComponents == 1)
            {
				if((ui32TOFlag & TO_FLAG_INTEGER) || psOperand->iIntegerImmediate || fpcheck(psOperand->afImmediates[0]))
				{
					bformata(glsl, "%d",
						*((int*)(&psOperand->afImmediates[0])));
				}
				else
				{
					bformata(glsl, "%f",
                    psOperand->afImmediates[0]);
				}
            }
            else
            if(psOperand->iNumComponents == 4)
            {
                if((ui32TOFlag & TO_FLAG_INTEGER) ||
                    psOperand->iIntegerImmediate ||
                    fpcheck(psOperand->afImmediates[0]) ||
                    fpcheck(psOperand->afImmediates[1]) ||
                    fpcheck(psOperand->afImmediates[2]) ||
                    fpcheck(psOperand->afImmediates[3]))
                {
                    bformata(glsl, "vec4(%d, %d, %d, %d)",
                        *(int*)&psOperand->afImmediates[0],
                        *(int*)&psOperand->afImmediates[1],
                        *(int*)&psOperand->afImmediates[2],
                        *(int*)&psOperand->afImmediates[3]);
                }
                else
                {
                    bformata(glsl, "vec4(%f, %f, %f, %f)",
                        psOperand->afImmediates[0],
                        psOperand->afImmediates[1],
                        psOperand->afImmediates[2],
                        psOperand->afImmediates[3]);
                }
            }
            break;
        }
        case OPERAND_TYPE_INPUT:
        {
            switch(psOperand->iIndexDims)
            {
                case INDEX_2D:
                {
                    if(psOperand->aui32ArraySizes[1] == 0)//Input index zero - position.
                    {
                        bcatcstr(glsl, "gl_in");
                        TranslateOperandIndex(psContext, psOperand, TO_FLAG_NONE);//Vertex index
                        bcatcstr(glsl, ".gl_Position");
                    }
                    else
                    {
                        const char* name = "Input";
                        if(ui32TOFlag & TO_FLAG_DECLARATION_NAME)
                        {
                            name = GetDeclaredName(psContext->psShader->eShaderType, psContext->flags);
                        }
                        
                        bformata(glsl, "%s%d", name, psOperand->aui32ArraySizes[1]);
                        TranslateOperandIndex(psContext, psOperand, TO_FLAG_NONE);//Vertex index
                    }
                    break;
                }
                default:
                {
                    if(psOperand->eIndexRep[0] == OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE)
                    {
                        bformata(glsl, "Input%d[int(", psOperand->ui32RegisterNumber);
                        TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE);
                        bcatcstr(glsl, ")]");
                    }
                    else
                    {
                        if(psContext->psShader->aIndexedInput[psOperand->ui32RegisterNumber] != 0)
                        {
                            const uint32_t parentIndex = psContext->psShader->aIndexedInputParents[psOperand->ui32RegisterNumber];
                            bformata(glsl, "Input%d[%d]", parentIndex,
                                psOperand->ui32RegisterNumber - parentIndex);
                        }
                        else
                        {
                            const char* name = "Input";
                            if(ui32TOFlag & TO_FLAG_DECLARATION_NAME)
                            {
                                name = GetDeclaredName(psContext->psShader->eShaderType, psContext->flags);
                            }

                            bformata(glsl, "%s%d", name, psOperand->ui32RegisterNumber);
                        }
                    }
                    break;
                }
            }
            break;
        }
        case OPERAND_TYPE_OUTPUT:
        {
            bformata(glsl, "Output%d", psOperand->ui32RegisterNumber);
            if(psOperand->psSubOperand[0])
            {
                bcatcstr(glsl, "[int("); //Indexes must be integral.
                TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE);
                bcatcstr(glsl, ")]");
            }
            break;
        }
        case OPERAND_TYPE_OUTPUT_DEPTH:
        case OPERAND_TYPE_OUTPUT_DEPTH_GREATER_EQUAL:
        case OPERAND_TYPE_OUTPUT_DEPTH_LESS_EQUAL:
        {
            bcatcstr(glsl, "gl_FragDepth");
            break;
        }
        case OPERAND_TYPE_TEMP:
        {
            bformata(glsl, "Temp%d", psOperand->ui32RegisterNumber);
            break;
        }
        case OPERAND_TYPE_CONSTANT_BUFFER:
        {
            const char* StageName = "VS";
            ConstantBuffer* psCBuf = NULL;
            GetConstantBufferFromBindingPoint(psOperand->aui32ArraySizes[0], &psContext->psShader->sInfo, &psCBuf);

            switch(psContext->psShader->eShaderType)
            {
                case PIXEL_SHADER:
                {
                    StageName = "PS";
                    break;
                }
                case HULL_SHADER:
                {
                    StageName = "HS";
                    break;
                }
                case DOMAIN_SHADER:
                {
                    StageName = "DS";
                    break;
                }
                case GEOMETRY_SHADER:
                {
                    StageName = "GS";
                    break;
                }
                default:
                {
                    break;
                }
            }


#if CBUFFER_USE_STRUCT_AND_NAMES
            {
                char* pszContBuffName;

                pszContBuffName = psCBuf->Name;
                
                if(psCBuf->Name[0] == '$')//$Global or $Param
                    pszContBuffName++;

                ASSERT(psOperand->aui32ArraySizes[1] < psCBuf->ui32NumVars);
                
                bformata(glsl, "%s%s.%s", pszContBuffName, StageName, psCBuf->asVars[psOperand->aui32ArraySizes[1]].Name);
            }
#else
			if(psContext->flags & HLSLCC_FLAG_UNIFORM_BUFFER_OBJECT)
			{
                if((psCBuf->Name[0] == '$') && (psContext->flags & HLSLCC_FLAG_GLOBAL_CONSTS_NEVER_IN_UBO))
                {
                    bformata(glsl, "Globals%s[%d]", StageName, psOperand->aui32ArraySizes[1]);
                }
                else
                {
				    //Each uniform block is given the HLSL consant buffer name.
				    //Within each uniform block is a constant array named ConstN
				    bformata(glsl, "Const%d[%d]", psOperand->aui32ArraySizes[0], psOperand->aui32ArraySizes[1]);
                }
			}
			else
			{
				//$Globals.
				if(psCBuf->Name[0] == '$')
				{
					bformata(glsl, "Globals%s[%d]", StageName, psOperand->aui32ArraySizes[1]);
				}
				else
				{
					bformata(glsl, "%s%s[%d]", psCBuf->Name, StageName, psOperand->aui32ArraySizes[1]);
				}
			}
#endif
            break;
        }
        case OPERAND_TYPE_RESOURCE:
        {
            TextureName(psContext, psOperand->ui32RegisterNumber, 0);
            break;
        }
        case OPERAND_TYPE_SAMPLER:
        {
            bformata(glsl, "Sampler%d", psOperand->ui32RegisterNumber);
            break;
        }
        case OPERAND_TYPE_FUNCTION_BODY:
        {
            const uint32_t ui32FuncBody = psOperand->ui32RegisterNumber;
            const uint32_t ui32FuncTable = psContext->psShader->aui32FuncBodyToFuncTable[ui32FuncBody];
            //const uint32_t ui32FuncPointer = psContext->psShader->aui32FuncTableToFuncPointer[ui32FuncTable];
            const uint32_t ui32ClassType = psContext->psShader->sInfo.aui32TableIDToTypeID[ui32FuncTable];
            const char* ClassTypeName = &psContext->psShader->sInfo.psClassTypes[ui32ClassType].Name[0];
            const uint32_t ui32UniqueClassFuncIndex = psContext->psShader->ui32NextClassFuncName[ui32ClassType]++;

            bformata(glsl, "%s_Func%d", ClassTypeName, ui32UniqueClassFuncIndex);
            break;
        }
		case OPERAND_TYPE_INPUT_FORK_INSTANCE_ID:
		{
			bcatcstr(glsl, "forkInstanceID");
            *pui32IgnoreSwizzle = 1;
			return;
		}
		case OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER:
		{
            bcatcstr(glsl, "immediateConstBufferF");

            if(psOperand->psSubOperand[0])
            {
                bcatcstr(glsl, "(int("); //Indexes must be integral.
                TranslateOperand(psContext, psOperand->psSubOperand[0], TO_FLAG_NONE);
                bcatcstr(glsl, "))");
            }
			break;
		}
		case OPERAND_TYPE_INPUT_DOMAIN_POINT:
		{
			bcatcstr(glsl, "gl_TessCoord");
			break;
		}
		case OPERAND_TYPE_INPUT_CONTROL_POINT:
		{
			if(psOperand->aui32ArraySizes[1] == 0)//Input index zero - position.
			{
				bformata(glsl, "gl_in[%d].gl_Position", psOperand->aui32ArraySizes[0]);
			}
            else
            {
                bformata(glsl, "Input%d[%d]", psOperand->aui32ArraySizes[1], psOperand->aui32ArraySizes[0]);
            }
            break;
		}
		case OPERAND_TYPE_NULL:
		{
			// Null register, used to discard results of operations
			bcatcstr(glsl, "//null");
			break;
		}
        case OPERAND_TYPE_OUTPUT_CONTROL_POINT_ID:
        {
            bcatcstr(glsl, "gl_InvocationID");
            *pui32IgnoreSwizzle = 1;
            break;
        }
        case OPERAND_TYPE_OUTPUT_COVERAGE_MASK:
        {
            bcatcstr(glsl, "gl_SampleMask[0]");
            *pui32IgnoreSwizzle = 1;
            break;
        }
        case OPERAND_TYPE_INPUT_COVERAGE_MASK:
        {
            bcatcstr(glsl, "gl_SampleMaskIn[0]");
            //Skip swizzle on scalar types.
            *pui32IgnoreSwizzle = 1;
            break;
        }
        default:
        {
            ASSERT(0);
            break;
        }
    }
}
Exemplo n.º 4
0
const uint32_t* DecodeDeclaration(Shader* psShader, const uint32_t* pui32Token, Declaration* psDecl)
{
    uint32_t ui32TokenLength = DecodeInstructionLength(*pui32Token);
    const uint32_t bExtended = DecodeIsOpcodeExtended(*pui32Token);
    const OPCODE_TYPE eOpcode = DecodeOpcodeType(*pui32Token);
    uint32_t ui32OperandOffset = 1;

    psDecl->eOpcode = eOpcode;

	psDecl->ui32IsShadowTex = 0;

    if(bExtended)
    {
        ui32OperandOffset = 2;
    }

    switch (eOpcode)
    {
        case OPCODE_DCL_RESOURCE: // DCL* opcodes have
        {
            psDecl->value.eResourceDimension = DecodeResourceDimension(*pui32Token);
            psDecl->ui32NumOperands = 1;
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            break;
        }
        case OPCODE_DCL_CONSTANT_BUFFER: // custom operand formats.
        {
            psDecl->ui32NumOperands = 1;
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            break;
        }
        case OPCODE_DCL_SAMPLER:
        {
            break;
        }
        case OPCODE_DCL_INDEX_RANGE:
        {
            psDecl->ui32NumOperands = 1;
            ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            psDecl->value.ui32IndexRange = pui32Token[ui32OperandOffset];

            if(psDecl->asOperands[0].eType == OPERAND_TYPE_INPUT)
            {
                uint32_t i;
                const uint32_t indexRange = psDecl->value.ui32IndexRange;
                const uint32_t reg = psDecl->asOperands[0].ui32RegisterNumber;

                psShader->aIndexedInput[reg] = indexRange;
                psShader->aIndexedInputParents[reg] = reg;

                //-1 means don't declare this input because it falls in
                //the range of an already declared array.
                for(i=reg+1; i<reg+indexRange; ++i)
                {
                    psShader->aIndexedInput[i] = -1;
                    psShader->aIndexedInputParents[i] = reg;
                }
            }

            if(psDecl->asOperands[0].eType == OPERAND_TYPE_OUTPUT)
            {
                psShader->aIndexedOutput[psDecl->asOperands[0].ui32RegisterNumber] = psDecl->value.ui32IndexRange;
            }
            break;
        }
        case OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY:
        {
            psDecl->value.eOutputPrimitiveTopology = DecodeGSOutputPrimitiveTopology(*pui32Token);
            break;
        }
        case OPCODE_DCL_GS_INPUT_PRIMITIVE:
        {
            psDecl->value.eInputPrimitive = DecodeGSInputPrimitive(*pui32Token);
            break;
        }
        case OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT:
        {
            psDecl->value.ui32MaxOutputVertexCount = pui32Token[1];
            break;
        }
        case OPCODE_DCL_TESS_PARTITIONING:
        {
            psDecl->value.eTessPartitioning = DecodeTessPartitioning(*pui32Token);
            break;
        }
        case OPCODE_DCL_TESS_DOMAIN:
        {
            psDecl->value.eTessDomain = DecodeTessDomain(*pui32Token);
            break;
        }
        case OPCODE_DCL_TESS_OUTPUT_PRIMITIVE:
        {
            psDecl->value.eTessOutPrim = DecodeTessOutPrim(*pui32Token);
            break;
        }
        case OPCODE_DCL_THREAD_GROUP:
        {
            psDecl->value.aui32WorkGroupSize[0] = pui32Token[1];
            psDecl->value.aui32WorkGroupSize[1] = pui32Token[2];
            psDecl->value.aui32WorkGroupSize[2] = pui32Token[3];
            break;
        }
        case OPCODE_DCL_INPUT:
        {
            psDecl->ui32NumOperands = 1;
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            break;
        }
        case OPCODE_DCL_INPUT_SIV:
        {
            psDecl->ui32NumOperands = 1;
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            if(psShader->eShaderType == PIXEL_SHADER)
            {
                psDecl->value.eInterpolation = DecodeInterpolationMode(*pui32Token);
                
            }
            break;
        }
        case OPCODE_DCL_INPUT_PS:
        {
            psDecl->ui32NumOperands = 1;
            psDecl->value.eInterpolation = DecodeInterpolationMode(*pui32Token);
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            break;
        }
        case OPCODE_DCL_INPUT_SGV:
        case OPCODE_DCL_INPUT_PS_SGV:
        {
            psDecl->ui32NumOperands = 1;
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            DecodeNameToken(pui32Token + 3, &psDecl->asOperands[0]);
            break;
        }
        case OPCODE_DCL_INPUT_PS_SIV:
        {
            psDecl->value.eInterpolation = DecodeInterpolationMode(*pui32Token);
            break;
        }
        case OPCODE_DCL_OUTPUT:
        {
            psDecl->ui32NumOperands = 1;
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            break;
        }
        case OPCODE_DCL_OUTPUT_SGV:
        {
            break;
        }
        case OPCODE_DCL_OUTPUT_SIV:
        {
            psDecl->ui32NumOperands = 1;
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            DecodeNameToken(pui32Token + 3, &psDecl->asOperands[0]);
            break;
        }
        case OPCODE_DCL_TEMPS:
        {
            psDecl->value.ui32NumTemps = *(pui32Token+ui32OperandOffset);
            break;
        }
        case OPCODE_DCL_INDEXABLE_TEMP:
        {
            break;
        }
        case OPCODE_DCL_GLOBAL_FLAGS:
        {
            psDecl->value.ui32GlobalFlags = DecodeGlobalFlags(*pui32Token);
            break;
        }
        case OPCODE_DCL_INTERFACE:
        {
            uint32_t func = 0, numClassesImplementingThisInterface, arrayLen, interfaceID;
            interfaceID = pui32Token[ui32OperandOffset];
            ui32OperandOffset++;
            psDecl->ui32TableLength = pui32Token[ui32OperandOffset];
            ui32OperandOffset++;

            numClassesImplementingThisInterface = DecodeInterfaceTableLength(*(pui32Token+ui32OperandOffset));
            arrayLen = DecodeInterfaceArrayLength(*(pui32Token+ui32OperandOffset));

            ui32OperandOffset++;

            psDecl->value.interface.ui32InterfaceID = interfaceID;
            psDecl->value.interface.ui32NumFuncTables = numClassesImplementingThisInterface;
            psDecl->value.interface.ui32ArraySize = arrayLen;

            psShader->funcPointer[interfaceID].ui32NumBodiesPerTable = psDecl->ui32TableLength;

            for(;func < numClassesImplementingThisInterface; ++func)
            {
                uint32_t ui32FuncTable = *(pui32Token+ui32OperandOffset);
                psShader->aui32FuncTableToFuncPointer[ui32FuncTable] = interfaceID;

                psShader->funcPointer[interfaceID].aui32FuncTables[func] = ui32FuncTable;
                ui32OperandOffset++;
            }

            break;
        }
        case OPCODE_DCL_FUNCTION_BODY:
        {
            psDecl->ui32NumOperands = 1;
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            break;
        }
        case OPCODE_DCL_FUNCTION_TABLE:
        {
            uint32_t ui32Func;
            const uint32_t ui32FuncTableID = pui32Token[ui32OperandOffset++];
            const uint32_t ui32NumFuncsInTable = pui32Token[ui32OperandOffset++];

            for(ui32Func=0; ui32Func<ui32NumFuncsInTable;++ui32Func)
            {
                const uint32_t ui32FuncBodyID = pui32Token[ui32OperandOffset++];

                psShader->aui32FuncBodyToFuncTable[ui32FuncBodyID] = ui32FuncTableID;

                psShader->funcTable[ui32FuncTableID].aui32FuncBodies[ui32Func] = ui32FuncBodyID;

            }

// OpcodeToken0 is followed by a DWORD that represents the function table
// identifier and another DWORD (TableLength) that gives the number of
// functions in the table.
//
// This is followed by TableLength DWORDs which are function body indices.
//

            break;
        }
		case OPCODE_DCL_INPUT_CONTROL_POINT_COUNT:
		{
			break;
		}
		case OPCODE_HS_DECLS:
		{
			break;
		}
		case OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT:
		{
			psDecl->value.ui32MaxOutputVertexCount = DecodeOutputControlPointCount(*pui32Token);
			break;
		}
		case OPCODE_HS_JOIN_PHASE:
		case OPCODE_HS_FORK_PHASE:
		case OPCODE_HS_CONTROL_POINT_PHASE:
		{
			break;
		}
		case OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT:
		{
            ASSERT(psShader->ui32ForkPhaseCount != 0);//Check for wrapping when we decrement.
            psDecl->value.aui32HullPhaseInstanceInfo[0] = psShader->ui32ForkPhaseCount-1;
            psDecl->value.aui32HullPhaseInstanceInfo[1] = pui32Token[1];
			break;
		}
		case OPCODE_CUSTOMDATA:
		{
			ui32TokenLength = pui32Token[1];
			{
				int iTupleSrc = 0, iTupleDest = 0;
				//const uint32_t ui32ConstCount = pui32Token[1] - 2;
				//const uint32_t ui32TupleCount = (ui32ConstCount / 4);
				CUSTOMDATA_CLASS eClass = DecodeCustomDataClass(pui32Token[0]);

				const uint32_t ui32NumVec4 = (ui32TokenLength - 2) / 4;
				uint32_t uIdx = 0;

				ICBVec4 const *pVec4Array = (void*) (pui32Token + 2);

				//The buffer will contain at least one value, but not more than 4096 scalars/1024 vec4's.
				ASSERT(ui32NumVec4 < MAX_IMMEDIATE_CONST_BUFFER_VEC4_SIZE);
		
				/* must be a multiple of 4 */
				ASSERT(((ui32TokenLength - 2) % 4) == 0);

				for (uIdx = 0; uIdx < ui32NumVec4; uIdx++)
				{
					psDecl->asImmediateConstBuffer[uIdx] = pVec4Array[uIdx];
				}

				psDecl->ui32NumOperands = ui32NumVec4;
			}
			break;
		}
        case OPCODE_DCL_HS_MAX_TESSFACTOR:
        {
            psDecl->value.fMaxTessFactor = *((float*)&pui32Token[1]);
            break;
        }
        case OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED:
        {
            psDecl->ui32NumOperands = 1;
            psDecl->value.eResourceDimension = DecodeResourceDimension(*pui32Token);
            psDecl->sUAV.ui32GloballyCoherentAccess = DecodeAccessCoherencyFlags(*pui32Token);
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            break;
        }
        case OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW:
        {
            ResourceBinding* psBinding = NULL;
            ConstantBuffer* psBuffer = NULL;

            psDecl->ui32NumOperands = 1;
            psDecl->sUAV.ui32GloballyCoherentAccess = DecodeAccessCoherencyFlags(*pui32Token);
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);

            if(GetResourceFromBindingPoint(RTYPE_UAV_RWBYTEADDRESS, psDecl->asOperands[0].ui32RegisterNumber, &psShader->sInfo, &psBinding))
            {
                GetConstantBufferFromBindingPoint(psBinding->ui32BindPoint, &psShader->sInfo, &psBuffer);
                psDecl->sUAV.ui32BufferSize = psBuffer->ui32TotalSizeInBytes;
            }
            break;
        }
        case OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED:
        {
            ResourceBinding* psBinding = NULL;
            ConstantBuffer* psBuffer = NULL;

            psDecl->ui32NumOperands = 1;
            psDecl->sUAV.ui32GloballyCoherentAccess = DecodeAccessCoherencyFlags(*pui32Token);
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);

            if(GetResourceFromBindingPoint(RTYPE_UAV_RWSTRUCTURED, psDecl->asOperands[0].ui32RegisterNumber, &psShader->sInfo, &psBinding))
            {
                GetUAVBufferFromBindingPoint(psBinding->ui32BindPoint, &psShader->sInfo, &psBuffer);
                psDecl->sUAV.ui32BufferSize = psBuffer->ui32TotalSizeInBytes;
            }
            break;
        }
        case OPCODE_DCL_RESOURCE_STRUCTURED:
        {
            psDecl->ui32NumOperands = 1;
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            break;
        }
        case OPCODE_DCL_RESOURCE_RAW:
        {
            psDecl->ui32NumOperands = 1;
            DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]);
            break;
        }
        default:
        {
            //Reached end of declarations
            return 0;
        }
    }

    return pui32Token + ui32TokenLength;
}
Exemplo n.º 5
0
SHADER_VARIABLE_TYPE GetOperandDataType(HLSLCrossCompilerContext* psContext, const Operand* psOperand)
{
    if(psOperand->eType == OPERAND_TYPE_TEMP)
    {
        SHADER_VARIABLE_TYPE eCurrentType;
		int i = 0;

		if(psOperand->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE)
		{
			return psOperand->aeDataType[psOperand->aui32Swizzle[0]];
		}
		if(psOperand->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE)
		{
			if(psOperand->ui32Swizzle == (NO_SWIZZLE))
			{
				return psOperand->aeDataType[0];
			}

			return psOperand->aeDataType[psOperand->aui32Swizzle[0]];
		}

		if(psOperand->eSelMode == OPERAND_4_COMPONENT_MASK_MODE)
		{
			uint32_t ui32CompMask = psOperand->ui32CompMask;
			if(!psOperand->ui32CompMask)
			{
				ui32CompMask = OPERAND_4_COMPONENT_MASK_ALL;
			}
			for(;i<4;++i)
			{
				if(ui32CompMask & (1<<i))
				{
					eCurrentType = psOperand->aeDataType[i];
					break;
				}
			}

#ifdef _DEBUG
			//Check if all elements have the same basic type.
			for(;i<4;++i)
			{
				if(psOperand->ui32CompMask & (1<<i))
				{
					if(eCurrentType != psOperand->aeDataType[i])
					{
						ASSERT(0);
					}
				}
			}
#endif
			return eCurrentType;
		}

		ASSERT(0);
    }
	else if(psOperand->eType == OPERAND_TYPE_OUTPUT)
	{
		const uint32_t ui32Register = psOperand->aui32ArraySizes[psOperand->iIndexDims-1];
		InOutSignature* psOut;

		if(GetOutputSignatureFromRegister(ui32Register, psOperand->ui32CompMask, &psContext->psShader->sInfo, &psOut))
		{
			if( psOut->eComponentType == INOUT_COMPONENT_UINT32)
			{
				return SVT_UINT;
			}
			else if( psOut->eComponentType == INOUT_COMPONENT_SINT32)
			{
				return SVT_INT;
			}
		}
	}
	else if(psOperand->eType == OPERAND_TYPE_INPUT)
	{
		const uint32_t ui32Register = psOperand->aui32ArraySizes[psOperand->iIndexDims-1];
		InOutSignature* psIn;

		if(GetInputSignatureFromRegister(ui32Register, &psContext->psShader->sInfo, &psIn))
		{
			if( psIn->eComponentType == INOUT_COMPONENT_UINT32)
			{
				return SVT_UINT;
			}
			else if( psIn->eComponentType == INOUT_COMPONENT_SINT32)
			{
				return SVT_INT;
			}
		}
	}
	else if(psOperand->eType == OPERAND_TYPE_CONSTANT_BUFFER)
	{
        ConstantBuffer* psCBuf = NULL;
        ShaderVar* psVar = NULL;
        int32_t index = -1;
		int foundVar;
        GetConstantBufferFromBindingPoint(psOperand->aui32ArraySizes[0], &psContext->psShader->sInfo, &psCBuf);
		foundVar = GetShaderVarFromOffset(psOperand->aui32ArraySizes[1], psOperand->aui32Swizzle, psCBuf, &psVar, &index);
		if(foundVar && index == -1 && psOperand->psSubOperand[1] == NULL)
		{
			return psVar->sType.Type;
		}
	}
	else if(psOperand->eType == OPERAND_TYPE_IMMEDIATE32)
	{
		return psOperand->iIntegerImmediate ? SVT_INT : SVT_FLOAT;
	}
    return SVT_FLOAT;
}