public DXConstantBufferData (string name,
                                MojoShader.MOJOSHADER_symbolRegisterSet set, 
                                MojoShader.MOJOSHADER_symbol[] symbols)
		{
			Name = name ?? string.Empty;

			ParameterIndex = new List<int> ();
			ParameterOffset = new List<int> ();
			Parameters = new List<DXEffectObject.d3dx_parameter> ();

			int minRegister = short.MaxValue;
			int maxRegister = 0;

			var registerSize = (set == MojoShader.MOJOSHADER_symbolRegisterSet.MOJOSHADER_SYMREGSET_BOOL ? 1 : 4) * 4;

			foreach (var symbol in symbols) {
				if (symbol.register_set != set)
					continue;

				// Create the parameter.
				var parm = GetParameterFromSymbol (symbol);

				var offset = (int)symbol.register_index * registerSize;
				parm.bufferOffset = offset;

				Parameters.Add (parm);
                ParameterOffset.Add(offset);

                minRegister = Math.Min(minRegister, (int)symbol.register_index);
                maxRegister = Math.Max(maxRegister, (int)(symbol.register_index + symbol.register_count));
            }

            Size = Math.Max(maxRegister - minRegister, 0) * registerSize;
        }
Example #2
0
        public static DXPreshader CreatePreshader(MojoShader.MOJOSHADER_preshader preshaderData)
        {
            var symbols = DXHelper.UnmarshalArray<MojoShader.MOJOSHADER_symbol>(
                    preshaderData.symbols, (int)preshaderData.symbol_count);

            var instructions = DXHelper.UnmarshalArray<MojoShader.MOJOSHADER_preshaderInstruction>(
                preshaderData.instructions, (int)preshaderData.instruction_count);

            var literals = DXHelper.UnmarshalArray<double>(
                preshaderData.literals, (int)preshaderData.literal_count);


            var preshader = new DXPreshader();

            preshader._temp_count = (int)preshaderData.temp_count;
            preshader._symbols = symbols;
            preshader._instructions = instructions;
            preshader._literals = literals;

            var input_count = 0;
            foreach (var symbol in symbols)
                input_count = Math.Max(input_count, (int)(symbol.register_index + symbol.register_count));            
            preshader._input_count = input_count;

            return preshader;
        }
Example #3
0
        static internal VertexElementUsage ToXNAVertexElementUsage(MojoShader.MOJOSHADER_usage usage)
        {
            switch (usage)
            {
                case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_POSITION:
                    return VertexElementUsage.Position;
		        case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_BLENDWEIGHT:
                    return VertexElementUsage.BlendWeight;
                case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_BLENDINDICES:
                    return VertexElementUsage.BlendIndices;
		        case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_NORMAL:
                    return VertexElementUsage.Normal;
                case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_POINTSIZE:
                    return VertexElementUsage.PointSize;
                case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_TEXCOORD:
                    return VertexElementUsage.TextureCoordinate;
                case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_TANGENT:
                    return VertexElementUsage.Tangent;
                case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_BINORMAL:
                    return VertexElementUsage.Binormal;
                case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_TESSFACTOR:
                    return VertexElementUsage.TessellateFactor;
                case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_COLOR:
                    return VertexElementUsage.Color;
                case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_FOG:
                    return VertexElementUsage.Fog;
                case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_DEPTH:
                    return VertexElementUsage.Depth;
                case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_SAMPLE:
                    return VertexElementUsage.Sample;

                default:
                    throw new NotImplementedException();
            }
        }
Example #4
0
        private unsafe void INTERNAL_updateSamplers(
			uint changeCount,
			MojoShader.MOJOSHADER_samplerStateRegister* registers,
			TextureCollection textures,
			SamplerStateCollection samplers
		)
        {
            for (int i = 0; i < changeCount; i += 1)
            {
                if (registers[i].sampler_state_count == 0)
                {
                    // Nothing to do
                    continue;
                }

                int register = (int) registers[i].sampler_register;

                /* We're going to store this state locally, then generate a
                 * new object later if needed. Otherwise the GC loses its
                 * mind.
                 * -flibit
                 */
                SamplerState oldSampler = samplers[register];

                // Used to prevent redundant sampler changes
                bool samplerChanged = false;
                bool filterChanged = false;

                // Current sampler state
                TextureAddressMode addressU = oldSampler.AddressU;
                TextureAddressMode addressV = oldSampler.AddressV;
                TextureAddressMode addressW = oldSampler.AddressW;
                int maxAnisotropy = oldSampler.MaxAnisotropy;
                int maxMipLevel = oldSampler.MaxMipLevel;
                float mipMapLODBias = oldSampler.MipMapLevelOfDetailBias;

                // Current sampler filter
                TextureFilter filter = oldSampler.Filter;
                MojoShader.MOJOSHADER_textureFilterType magFilter = XNAMag[(int) filter];
                MojoShader.MOJOSHADER_textureFilterType minFilter = XNAMin[(int) filter];
                MojoShader.MOJOSHADER_textureFilterType mipFilter = XNAMip[(int) filter];

                MojoShader.MOJOSHADER_effectSamplerState* states = (MojoShader.MOJOSHADER_effectSamplerState*) registers[i].sampler_states;
                for (int j = 0; j < registers[i].sampler_state_count; j += 1)
                {
                    MojoShader.MOJOSHADER_samplerStateType type = states[j].type;
                    if (type == MojoShader.MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_TEXTURE)
                    {
                        string samplerName = Marshal.PtrToStringAnsi(
                            registers[i].sampler_name
                        );
                        if (samplerMap.ContainsKey(samplerName))
                        {
                            Texture texture = samplerMap[samplerName].texture;
                            if (texture != null)
                            {
                                textures[register] = texture;
                            }
                        }
                    }
                    else if (type == MojoShader.MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_ADDRESSU)
                    {
                        MojoShader.MOJOSHADER_textureAddress* val = (MojoShader.MOJOSHADER_textureAddress*) states[j].value.values;
                        addressU = XNAAddress[(int) *val];
                        samplerChanged = true;
                    }
                    else if (type == MojoShader.MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_ADDRESSV)
                    {
                        MojoShader.MOJOSHADER_textureAddress* val = (MojoShader.MOJOSHADER_textureAddress*) states[j].value.values;
                        addressV = XNAAddress[(int) *val];
                        samplerChanged = true;
                    }
                    else if (type == MojoShader.MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_ADDRESSW)
                    {
                        MojoShader.MOJOSHADER_textureAddress* val = (MojoShader.MOJOSHADER_textureAddress*) states[j].value.values;
                        addressW = XNAAddress[(int) *val];
                        samplerChanged = true;
                    }
                    else if (type == MojoShader.MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MAGFILTER)
                    {
                        MojoShader.MOJOSHADER_textureFilterType* val = (MojoShader.MOJOSHADER_textureFilterType*) states[j].value.values;
                        magFilter = *val;
                        filterChanged = true;
                    }
                    else if (type == MojoShader.MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MINFILTER)
                    {
                        MojoShader.MOJOSHADER_textureFilterType* val = (MojoShader.MOJOSHADER_textureFilterType*) states[j].value.values;
                        minFilter = *val;
                        filterChanged = true;
                    }
                    else if (type == MojoShader.MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MIPFILTER)
                    {
                        MojoShader.MOJOSHADER_textureFilterType* val = (MojoShader.MOJOSHADER_textureFilterType*) states[j].value.values;
                        mipFilter = *val;
                        filterChanged = true;
                    }
                    else if (type == MojoShader.MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MIPMAPLODBIAS)
                    {
                        float* val = (float*) states[i].value.values;
                        mipMapLODBias = *val;
                        samplerChanged = true;
                    }
                    else if (type == MojoShader.MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MAXMIPLEVEL)
                    {
                        int* val = (int*) states[i].value.values;
                        maxMipLevel = *val;
                        samplerChanged = true;
                    }
                    else if (type == MojoShader.MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MAXANISOTROPY)
                    {
                        int* val = (int*) states[i].value.values;
                        maxAnisotropy = *val;
                        samplerChanged = true;
                    }
                    else
                    {
                        throw new Exception("Unhandled sampler state!");
                    }
                }
                if (filterChanged)
                {
                    if (	magFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC ||
                        minFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC ||
                        mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC	)
                    {
                        // Just assume we wanted Anisotropic if any of these qualify.
                        filter = TextureFilter.Anisotropic;
                    }
                    else if (magFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT)
                    {
                        if (minFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT)
                        {
                            if (	mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_NONE ||
                                mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT	)
                            {
                                filter = TextureFilter.Point;
                            }
                            else if (mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR)
                            {
                                filter = TextureFilter.PointMipLinear;
                            }
                            else
                            {
                                throw new NotImplementedException("Unhandled mipfilter type!");
                            }
                        }
                        else if (minFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR)
                        {
                            if (	mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_NONE ||
                                mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT	)
                            {
                                filter = TextureFilter.MinLinearMagPointMipPoint;
                            }
                            else if (mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR)
                            {
                                filter = TextureFilter.MinLinearMagPointMipLinear;
                            }
                            else
                            {
                                throw new NotImplementedException("Unhandled mipfilter type!");
                            }
                        }
                        else
                        {
                            throw new NotImplementedException("Unhandled minfilter type!");
                        }
                    }
                    else if (magFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR)
                    {
                        if (minFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT)
                        {
                            if (	mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_NONE ||
                                mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT	)
                            {
                                filter = TextureFilter.MinPointMagLinearMipPoint;
                            }
                            else if (mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR)
                            {
                                filter = TextureFilter.MinPointMagLinearMipLinear;
                            }
                            else
                            {
                                throw new NotImplementedException("Unhandled mipfilter type!");
                            }
                        }
                        else if (minFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR)
                        {
                            if (	mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_NONE ||
                                mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT	)
                            {
                                filter = TextureFilter.LinearMipPoint;
                            }
                            else if (mipFilter == MojoShader.MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR)
                            {
                                filter = TextureFilter.Linear;
                            }
                            else
                            {
                                throw new NotImplementedException("Unhandled mipfilter type!");
                            }
                        }
                        else
                        {
                            throw new NotImplementedException("Unhandled minfilter type!");
                        }
                    }
                    else
                    {
                        throw new NotImplementedException("Unhandled magfilter type!");
                    }
                    samplerChanged = true;
                }

                if (samplerChanged)
                {
                    // FIXME: This is part of the state cache hack! -flibit
                    SamplerState newSampler;
                    if (samplers[register] == samplerCache[register])
                    {
                        // FIXME: 30 is arbitrary! -flibit
                        newSampler = samplerCache[register + 30];
                    }
                    else
                    {
                        newSampler = samplerCache[register];
                    }
                    newSampler.Filter = filter;
                    newSampler.AddressU = addressU;
                    newSampler.AddressV = addressV;
                    newSampler.AddressW = addressW;
                    newSampler.MaxAnisotropy = maxAnisotropy;
                    newSampler.MaxMipLevel = maxMipLevel;
                    newSampler.MipMapLevelOfDetailBias = mipMapLODBias;
                    samplers[register] = newSampler;
                }
            }
        }
Example #5
0
		public void BeginPassRestore(
			IGLEffect effect,
			ref MojoShader.MOJOSHADER_effectStateChanges changes
		) {
			IntPtr glEffectData = (effect as OpenGLEffect).GLEffectData;
			uint whatever;
			MojoShader.MOJOSHADER_glEffectBegin(
				glEffectData,
				out whatever,
				1,
				ref changes
			);
			MojoShader.MOJOSHADER_glEffectBeginPass(
				glEffectData,
				0
			);
			effectApplied = true;
		}
Example #6
0
		public void ApplyEffect(
			IGLEffect effect,
			IntPtr technique,
			uint pass,
			ref MojoShader.MOJOSHADER_effectStateChanges stateChanges
		) {
			effectApplied = true;
			IntPtr glEffectData = (effect as OpenGLEffect).GLEffectData;
			if (glEffectData == currentEffect)
			{
				if (technique == currentTechnique && pass == currentPass)
				{
					MojoShader.MOJOSHADER_glEffectCommitChanges(currentEffect);
					return;
				}
				MojoShader.MOJOSHADER_glEffectEndPass(currentEffect);
				MojoShader.MOJOSHADER_glEffectBeginPass(currentEffect, pass);
				currentTechnique = technique;
				currentPass = pass;
				return;
			}
			else if (currentEffect != IntPtr.Zero)
			{
				MojoShader.MOJOSHADER_glEffectEndPass(currentEffect);
				MojoShader.MOJOSHADER_glEffectEnd(currentEffect);
			}
			uint whatever;
			MojoShader.MOJOSHADER_glEffectBegin(
				glEffectData,
				out whatever,
				0,
				ref stateChanges
			);
			MojoShader.MOJOSHADER_glEffectBeginPass(
				glEffectData,
				pass
			);
			currentEffect = glEffectData;
			currentTechnique = technique;
			currentPass = pass;
		}
        private static DXEffectObject.d3dx_parameter GetParameterFromSymbol(MojoShader.MOJOSHADER_symbol symbol)
        {
            var param = new DXEffectObject.d3dx_parameter();
            param.rows = symbol.info.rows;
            param.columns = symbol.info.columns;
            param.name = symbol.name ?? string.Empty;
            param.semantic = string.Empty; // TODO: How do i do this with only MojoShader?

            var registerSize = (symbol.register_set == MojoShader.MOJOSHADER_symbolRegisterSet.MOJOSHADER_SYMREGSET_BOOL ? 1 : 4) * 4;
            var offset = (int)symbol.register_index * registerSize;
            param.bufferOffset = offset;

            switch (symbol.info.parameter_class)
            {
                case MojoShader.MOJOSHADER_symbolClass.MOJOSHADER_SYMCLASS_SCALAR:
                    param.class_ = DXEffectObject.D3DXPARAMETER_CLASS.SCALAR;
                    break;

                case MojoShader.MOJOSHADER_symbolClass.MOJOSHADER_SYMCLASS_VECTOR:
                    param.class_ = DXEffectObject.D3DXPARAMETER_CLASS.VECTOR;
                    break;

                case MojoShader.MOJOSHADER_symbolClass.MOJOSHADER_SYMCLASS_MATRIX_COLUMNS:
                    param.class_ = DXEffectObject.D3DXPARAMETER_CLASS.MATRIX_COLUMNS;
                    break;

                default:
                    throw new Exception("Unsupported parameter class!");
            }

            switch (symbol.info.parameter_type)
            {
                case MojoShader.MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_BOOL:
                    param.type = DXEffectObject.D3DXPARAMETER_TYPE.BOOL;
                    break;

                case MojoShader.MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_FLOAT:
                    param.type = DXEffectObject.D3DXPARAMETER_TYPE.FLOAT;
                    break;

                case MojoShader.MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_INT:
                    param.type = DXEffectObject.D3DXPARAMETER_TYPE.INT;
                    break;

                default:
                    throw new Exception("Unsupported parameter type!");
            }

            // HACK: We don't have real default parameters from mojoshader! 
            param.data = new byte[param.rows * param.columns * 4];

            param.member_count = symbol.info.member_count;
            param.element_count = symbol.info.elements > 1 ? symbol.info.elements : 0;

            if (param.member_count > 0)
            {
                param.member_handles = new DXEffectObject.d3dx_parameter[param.member_count];

                var members = DXHelper.UnmarshalArray<MojoShader.MOJOSHADER_symbol>(
                    symbol.info.members, (int)symbol.info.member_count);

                for (var i = 0; i < param.member_count; i++)
                {
                    var mparam = GetParameterFromSymbol(members[i]);
                    param.member_handles[i] = mparam;
                }
            }
            else
            {
                param.member_handles = new DXEffectObject.d3dx_parameter[param.element_count];
                for (var i = 0; i < param.element_count; i++)
                {
                    var mparam = new DXEffectObject.d3dx_parameter();

                    mparam.name = string.Empty;
                    mparam.semantic = string.Empty;
                    mparam.type = param.type;
                    mparam.class_ = param.class_;
                    mparam.rows = param.rows;
                    mparam.columns = param.columns;
                    mparam.data = new byte[param.columns * param.rows * 4];

                    param.member_handles[i] = mparam;
                }
            }

            return param;
        }