public virtual void ReadXml(XmlNode node, string ddsfolder) { Name = Xml.GetChildInnerText(node, "Name"); NameHash = JenkHash.GenHash(Name?.ToLowerInvariant()); Unknown_32h = (ushort)Xml.GetChildUIntAttribute(node, "Unk32", "value"); Usage = Xml.GetChildEnumInnerText <TextureUsage>(node, "Usage"); UsageFlags = Xml.GetChildEnumInnerText <TextureUsageFlags>(node, "UsageFlags"); ExtraFlags = Xml.GetChildUIntAttribute(node, "ExtraFlags", "value"); }
public TextureDescriptor(int binding, SamplerType type, TextureFormat format, int cbufSlot, int handleIndex) { Binding = binding; Type = type; Format = format; CbufSlot = cbufSlot; HandleIndex = handleIndex; Flags = TextureUsageFlags.None; }
/// <summary> /// Updates the texture scale for a given texture or image. /// </summary> /// <param name="texture">Start GPU virtual address of the pool</param> /// <param name="usageFlags">The related texture usage flags</param> /// <param name="index">The texture/image binding index</param> /// <param name="stage">The active shader stage</param> /// <returns>True if the given texture has become blacklisted, indicating that its host texture may have changed.</returns> private bool UpdateScale(Texture texture, TextureUsageFlags usageFlags, int index, ShaderStage stage) { float result = 1f; bool changed = false; if ((usageFlags & TextureUsageFlags.NeedsScaleValue) != 0 && texture != null) { if ((usageFlags & TextureUsageFlags.ResScaleUnsupported) != 0) { changed = texture.ScaleMode != TextureScaleMode.Blacklisted; texture.BlacklistScale(); } else { switch (stage) { case ShaderStage.Fragment: float scale = texture.ScaleFactor; if (scale != 1) { Texture activeTarget = _channel.TextureManager.GetAnyRenderTarget(); if (activeTarget != null && (activeTarget.Info.Width / (float)texture.Info.Width) == (activeTarget.Info.Height / (float)texture.Info.Height)) { // If the texture's size is a multiple of the sampler size, enable interpolation using gl_FragCoord. (helps "invent" new integer values between scaled pixels) result = -scale; break; } } result = scale; break; case ShaderStage.Vertex: int fragmentIndex = (int)ShaderStage.Fragment - 1; index += _textureBindingsCount[fragmentIndex] + _imageBindingsCount[fragmentIndex]; result = texture.ScaleFactor; break; case ShaderStage.Compute: result = texture.ScaleFactor; break; } } } if (result != _scales[index]) { _scaleChanged = true; _scales[index] = result; } return(changed); }
/// <summary> /// Constructs the texture binding information structure. /// </summary> /// <param name="target">The shader sampler target type</param> /// <param name="format">Format of the image as declared on the shader</param> /// <param name="binding">The shader texture binding point</param> /// <param name="cbufSlot">Constant buffer slot where the texture handle is located</param> /// <param name="handle">The shader texture handle (read index into the texture constant buffer)</param> /// <param name="flags">The texture's usage flags, indicating how it is used in the shader</param> public TextureBindingInfo(Target target, Format format, int binding, int cbufSlot, int handle, TextureUsageFlags flags) { Target = target; Format = format; Binding = binding; CbufSlot = cbufSlot; Handle = handle; Flags = flags; }
/// <summary> /// Constructs the bindless texture binding information structure. /// </summary> /// <param name="target">The shader sampler target type</param> /// <param name="cbufSlot">Constant buffer slot where the bindless texture handle is located</param> /// <param name="cbufOffset">Constant buffer offset of the bindless texture handle</param> /// <param name="flags">The texture's usage flags, indicating how it is used in the shader</param> public TextureBindingInfo(Target target, int cbufSlot, int cbufOffset, TextureUsageFlags flags) { Target = target; Handle = 0; IsBindless = true; CbufSlot = cbufSlot; CbufOffset = cbufOffset; Flags = flags; }
/// <summary> /// Constructs the texture binding information structure. /// </summary> /// <param name="target">The shader sampler target type</param> /// <param name="handle">The shader texture handle (read index into the texture constant buffer)</param> /// <param name="flags">The texture's usage flags, indicating how it is used in the shader</param> public TextureBindingInfo(Target target, int handle, TextureUsageFlags flags) { Target = target; Handle = handle; IsBindless = false; CbufSlot = 0; CbufOffset = 0; Flags = flags; }
public TextureDescriptor(string name, SamplerType type, int cbufSlot, int cbufOffset) { Name = name; Type = type; HandleIndex = 0; IsBindless = true; CbufSlot = cbufSlot; CbufOffset = cbufOffset; Flags = TextureUsageFlags.None; }
public TextureDescriptor(string name, SamplerType type, int handleIndex) { Name = name; Type = type; HandleIndex = handleIndex; IsBindless = false; CbufSlot = 0; CbufOffset = 0; Flags = TextureUsageFlags.None; }
public static string ImageLoadOrStore(CodeGenContext context, AstOperation operation) { AstTextureOperation texOp = (AstTextureOperation)operation; bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0; // TODO: Bindless texture support. For now we just return 0/do nothing. if (isBindless) { return(texOp.Inst == Instruction.ImageLoad ? NumberFormatter.FormatFloat(0) : "// imageStore(bindless)"); } bool isArray = (texOp.Type & SamplerType.Array) != 0; bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0; string texCall = texOp.Inst == Instruction.ImageLoad ? "imageLoad" : "imageStore"; int srcIndex = isBindless ? 1 : 0; string Src(VariableType type) { return(GetSoureExpr(context, texOp.GetSource(srcIndex++), type)); } string indexExpr = null; if (isIndexed) { indexExpr = Src(VariableType.S32); } string imageName = OperandManager.GetImageName(context.Config.Stage, texOp, indexExpr); texCall += "(" + imageName; int coordsCount = texOp.Type.GetDimensions(); int pCount = coordsCount + (isArray ? 1 : 0); void Append(string str) { texCall += ", " + str; } string ApplyScaling(string vector) { int index = context.FindImageDescriptorIndex(texOp); TextureUsageFlags flags = TextureUsageFlags.NeedsScaleValue; if ((context.Config.Stage == ShaderStage.Fragment || context.Config.Stage == ShaderStage.Compute) && texOp.Inst == Instruction.ImageLoad && !isBindless && !isIndexed) { // Image scales start after texture ones. int scaleIndex = context.TextureDescriptors.Count + index; if (pCount == 3 && isArray) { // The array index is not scaled, just x and y. vector = "ivec3(Helper_TexelFetchScale((" + vector + ").xy, " + scaleIndex + "), (" + vector + ").z)"; } else if (pCount == 2 && !isArray) { vector = "Helper_TexelFetchScale(" + vector + ", " + scaleIndex + ")"; } else { flags |= TextureUsageFlags.ResScaleUnsupported; } } else { flags |= TextureUsageFlags.ResScaleUnsupported; } if (!isBindless) { context.ImageDescriptors[index] = context.ImageDescriptors[index].SetFlag(flags); } return(vector); } if (pCount > 1) { string[] elems = new string[pCount]; for (int index = 0; index < pCount; index++) { elems[index] = Src(VariableType.S32); } Append(ApplyScaling("ivec" + pCount + "(" + string.Join(", ", elems) + ")")); } else { Append(Src(VariableType.S32)); } if (texOp.Inst == Instruction.ImageStore) { VariableType type = texOp.Format.GetComponentType(); string[] cElems = new string[4]; for (int index = 0; index < 4; index++) { if (srcIndex < texOp.SourcesCount) { cElems[index] = Src(type); } else { cElems[index] = type switch { VariableType.S32 => NumberFormatter.FormatInt(0), VariableType.U32 => NumberFormatter.FormatUint(0), _ => NumberFormatter.FormatFloat(0) }; } } string prefix = type switch { VariableType.S32 => "i", VariableType.U32 => "u", _ => string.Empty }; Append(prefix + "vec4(" + string.Join(", ", cElems) + ")"); } texCall += ")" + (texOp.Inst == Instruction.ImageLoad ? GetMask(texOp.Index) : ""); return(texCall); }
public TextureDescriptor SetFlag(TextureUsageFlags flag) { Flags |= flag; return(this); }
/// <summary> /// Constructs the texture binding information structure. /// </summary> /// <param name="target">The shader sampler target type</param> /// <param name="handle">The shader texture handle (read index into the texture constant buffer)</param> /// <param name="flags">The texture's usage flags, indicating how it is used in the shader</param> public TextureBindingInfo(Target target, int handle, TextureUsageFlags flags) : this(target, (Format)0, handle, flags) { }