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; }
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; }
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(); } }
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; } } }
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; }
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; }