diff --git a/Source/Toolkit/SharpDX.Toolkit.Graphics/ShaderResourceViewSelector.cs b/Source/Toolkit/SharpDX.Toolkit.Graphics/ShaderResourceViewSelector.cs index 47665c6f2..98a3f721f 100644 --- a/Source/Toolkit/SharpDX.Toolkit.Graphics/ShaderResourceViewSelector.cs +++ b/Source/Toolkit/SharpDX.Toolkit.Graphics/ShaderResourceViewSelector.cs @@ -37,10 +37,11 @@ internal ShaderResourceViewSelector(Texture thisTexture) /// /// Gets a specific from this texture. /// - /// Type of the view slice. - /// The texture array slice index. - /// The mip map slice index. + /// The view format. + /// Type of the view. + /// The array or depth slice. + /// Index of the mip. /// An - public TextureView this[ViewType viewType, int arrayOrDepthSlice, int mipIndex] { get { return this.texture.GetShaderResourceView(viewType, arrayOrDepthSlice, mipIndex); } } + public TextureView this[DXGI.Format viewFormat, ViewType viewType, int arrayOrDepthSlice, int mipIndex] { get { return this.texture.GetShaderResourceView(viewFormat, viewType, arrayOrDepthSlice, mipIndex); } } } } \ No newline at end of file diff --git a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture.cs b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture.cs index aa54e068d..b9938cea6 100644 --- a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture.cs +++ b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture.cs @@ -19,6 +19,7 @@ // THE SOFTWARE. using System; +using System.Collections.Generic; using System.IO; using SharpDX.DXGI; using SharpDX.Direct3D11; @@ -72,7 +73,8 @@ public abstract class Texture : GraphicsResource, IComparable /// internal readonly int DepthStride; - internal TextureView[] shaderResourceViews; + internal TextureView defaultShaderResourceView; + internal Dictionary shaderResourceViews; internal TextureView[] renderTargetViews; internal UnorderedAccessView[] unorderedAccessViews; private MipMapDescription[] mipmapDescriptions; @@ -811,11 +813,12 @@ public void SetData(GraphicsDevice graphicsDevice, Image image) /// /// Gets a specific from this texture. /// + /// /// Type of the view slice. /// The texture array slice index. /// The mip map slice index. /// An - internal abstract TextureView GetShaderResourceView(ViewType viewType, int arrayOrDepthSlice, int mipIndex); + internal abstract TextureView GetShaderResourceView(Format viewFormat, ViewType viewType, int arrayOrDepthSlice, int mipIndex); /// /// Gets a specific from this texture. @@ -840,7 +843,7 @@ public void SetData(GraphicsDevice graphicsDevice, Image image) /// Source for the. public static implicit operator ShaderResourceView(Texture from) { - return @from == null ? null : @from.shaderResourceViews != null ? @from.shaderResourceViews[0] : null; + return @from == null ? null : from.defaultShaderResourceView; } /// @@ -1093,10 +1096,12 @@ protected override void OnPropertyChanged(string propertyName) { if (this.shaderResourceViews != null) { - for (int i = 0; i < this.shaderResourceViews.Length; i++) + int i = 0; + foreach(var shaderResourceViewItem in shaderResourceViews) { - var shaderResourceView = this.shaderResourceViews[i]; + var shaderResourceView = shaderResourceViewItem.Value; if (shaderResourceView != null) shaderResourceView.View.DebugName = Name == null ? null : String.Format("{0} SRV[{1}]", i, Name); + i++; } } @@ -1199,5 +1204,57 @@ internal static BindFlags GetBindFlagsFromTextureFlags(TextureFlags flags) return bindFlags; } + + internal struct TextureViewKey : IEquatable + { + public TextureViewKey(Format viewFormat, ViewType viewType, int arrayOrDepthSlice, int mipIndex) + { + ViewFormat = viewFormat; + ViewType = viewType; + ArrayOrDepthSlice = arrayOrDepthSlice; + MipIndex = mipIndex; + } + + public readonly DXGI.Format ViewFormat; + + public readonly ViewType ViewType; + + public readonly int ArrayOrDepthSlice; + + public readonly int MipIndex; + + public bool Equals(TextureViewKey other) + { + return ViewFormat == other.ViewFormat && ViewType == other.ViewType && ArrayOrDepthSlice == other.ArrayOrDepthSlice && MipIndex == other.MipIndex; + } + + public override bool Equals(object obj) + { + if(ReferenceEquals(null, obj)) return false; + return obj is TextureViewKey && Equals((TextureViewKey)obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = (int)ViewFormat; + hashCode = (hashCode * 397) ^ (int)ViewType; + hashCode = (hashCode * 397) ^ ArrayOrDepthSlice; + hashCode = (hashCode * 397) ^ MipIndex; + return hashCode; + } + } + + public static bool operator ==(TextureViewKey left, TextureViewKey right) + { + return left.Equals(right); + } + + public static bool operator !=(TextureViewKey left, TextureViewKey right) + { + return !left.Equals(right); + } + } } } \ No newline at end of file diff --git a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture1D.cs b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture1D.cs index e83a6be0e..dd00dee2f 100644 --- a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture1D.cs +++ b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture1D.cs @@ -129,7 +129,7 @@ public static Texture1D New(GraphicsDevice device, int width, PixelFormat format /// ID3D11Device::CreateTexture1D public static Texture1D New(GraphicsDevice device, int width, MipMapCount mipCount, PixelFormat format, TextureFlags flags = TextureFlags.ShaderResource, int arraySize = 1, ResourceUsage usage = ResourceUsage.Default) { - return new Texture1D(device, NewDescription(width, format, flags | TextureFlags.ShaderResource, mipCount, arraySize, usage)); + return new Texture1D(device, NewDescription(width, format, flags, mipCount, arraySize, usage)); } /// @@ -151,7 +151,7 @@ public static Texture1D New(GraphicsDevice device, int width, MipMapCount mipCou /// public unsafe static Texture1D New(GraphicsDevice device, int width, PixelFormat format, T[] textureData, TextureFlags flags = TextureFlags.ShaderResource, ResourceUsage usage = ResourceUsage.Immutable) where T : struct { - return new Texture1D(device, NewDescription(width, format, flags | TextureFlags.ShaderResource, 1, 1, usage), GetDataBox(format, width, 1, 1, textureData, (IntPtr)Interop.Fixed(textureData))); + return new Texture1D(device, NewDescription(width, format, flags, 1, 1, usage), GetDataBox(format, width, 1, 1, textureData, (IntPtr)Interop.Fixed(textureData))); } /// @@ -171,7 +171,7 @@ public static Texture1D New(GraphicsDevice device, Image image, TextureFlags fla if (image.Description.Dimension != TextureDimension.Texture1D) throw new ArgumentException("Invalid image. Must be 1D", "image"); - return new Texture1D(device, CreateTextureDescriptionFromImage(image, flags | TextureFlags.ShaderResource, usage), image.ToDataBox()); + return new Texture1D(device, CreateTextureDescriptionFromImage(image, flags, usage), image.ToDataBox()); } /// @@ -185,7 +185,7 @@ public static Texture1D New(GraphicsDevice device, Image image, TextureFlags fla /// A texture public static new Texture1D Load(GraphicsDevice device, Stream stream, TextureFlags flags = TextureFlags.ShaderResource, ResourceUsage usage = ResourceUsage.Immutable) { - var texture = Texture.Load(device, stream, flags | TextureFlags.ShaderResource, usage); + var texture = Texture.Load(device, stream, flags, usage); if (!(texture is Texture1D)) throw new ArgumentException(string.Format("Texture is not type of [Texture1D] but [{0}]", texture.GetType().Name)); return (Texture1D)texture; diff --git a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture1DBase.cs b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture1DBase.cs index 5c3729877..e3a5cea39 100644 --- a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture1DBase.cs +++ b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture1DBase.cs @@ -18,8 +18,10 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +using System.Collections.Generic; using SharpDX.Direct3D; using SharpDX.Direct3D11; +using SharpDX.DXGI; namespace SharpDX.Toolkit.Graphics { @@ -86,7 +88,7 @@ public override Texture ToStaging() return new Texture1D(this.GraphicsDevice, this.Description.ToStagingDescription()); } - internal override TextureView GetShaderResourceView(ViewType viewType, int arrayOrDepthSlice, int mipIndex) + internal override TextureView GetShaderResourceView(Format viewFormat, ViewType viewType, int arrayOrDepthSlice, int mipIndex) { if ((this.Description.BindFlags & BindFlags.ShaderResource) == 0) return null; @@ -95,14 +97,13 @@ internal override TextureView GetShaderResourceView(ViewType viewType, int array int mipCount; GetViewSliceBounds(viewType, ref arrayOrDepthSlice, ref mipIndex, out arrayCount, out mipCount); - var srvIndex = GetViewIndex(viewType, arrayOrDepthSlice, mipIndex); + var textureViewKey = new TextureViewKey(viewFormat, viewType, arrayOrDepthSlice, mipIndex); lock (this.shaderResourceViews) { - var srv = this.shaderResourceViews[srvIndex]; - + TextureView srv; // Creates the shader resource view - if (srv == null) + if (!shaderResourceViews.TryGetValue(textureViewKey, out srv)) { // Create the view var srvDescription = new ShaderResourceViewDescription() { Format = this.Description.Format }; @@ -125,7 +126,7 @@ internal override TextureView GetShaderResourceView(ViewType viewType, int array } srv = new TextureView(this, new ShaderResourceView(this.GraphicsDevice, this.Resource, srvDescription)); - this.shaderResourceViews[srvIndex] = ToDispose(srv); + this.shaderResourceViews.Add(textureViewKey, ToDispose(srv)); } return srv; @@ -187,10 +188,15 @@ protected override void InitializeViews() // Creates the shader resource view if ((this.Description.BindFlags & BindFlags.ShaderResource) != 0) { - this.shaderResourceViews = new TextureView[GetViewCount()]; + shaderResourceViews = new Dictionary(); // Pre initialize by default the view on the first array/mipmap - GetShaderResourceView(ViewType.Full, 0, 0); + var viewFormat = Format; + if (!FormatHelper.IsTypeless(viewFormat)) + { + // Only valid for non-typeless viewformat + defaultShaderResourceView = GetShaderResourceView(viewFormat, ViewType.Full, 0, 0); + } } // Creates the unordered access view diff --git a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture2D.cs b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture2D.cs index cdce3717d..b05718c85 100644 --- a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture2D.cs +++ b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture2D.cs @@ -128,7 +128,7 @@ public static Texture2D New(GraphicsDevice device, int width, int height, PixelF /// ID3D11Device::CreateTexture2D public static Texture2D New(GraphicsDevice device, int width, int height, MipMapCount mipCount, PixelFormat format, TextureFlags flags = TextureFlags.ShaderResource, int arraySize = 1, ResourceUsage usage = ResourceUsage.Default) { - return new Texture2D(device, NewDescription(width, height, format, flags | TextureFlags.ShaderResource, mipCount, arraySize, usage)); + return new Texture2D(device, NewDescription(width, height, format, flags, mipCount, arraySize, usage)); } /// @@ -172,7 +172,7 @@ public static Texture2D New(GraphicsDevice device, int width, int height, MipMap /// ID3D11Device::CreateTexture2D public static Texture2D New(GraphicsDevice device, int width, int height, MipMapCount mipCount, PixelFormat format, DataBox[] textureData, TextureFlags flags = TextureFlags.ShaderResource, int arraySize = 1, ResourceUsage usage = ResourceUsage.Default) { - return new Texture2D(device, NewDescription(width, height, format, flags | TextureFlags.ShaderResource, mipCount, arraySize, usage), textureData); + return new Texture2D(device, NewDescription(width, height, format, flags, mipCount, arraySize, usage), textureData); } /// @@ -192,7 +192,7 @@ public static Texture2D New(GraphicsDevice device, Image image, TextureFlags fla if (image.Description.Dimension != TextureDimension.Texture2D) throw new ArgumentException("Invalid image. Must be 2D", "image"); - return new Texture2D(device, CreateTextureDescriptionFromImage(image, flags | TextureFlags.ShaderResource, usage), image.ToDataBox()); + return new Texture2D(device, CreateTextureDescriptionFromImage(image, flags, usage), image.ToDataBox()); } /// @@ -206,7 +206,7 @@ public static Texture2D New(GraphicsDevice device, Image image, TextureFlags fla /// A texture public static new Texture2D Load(GraphicsDevice device, Stream stream, TextureFlags flags = TextureFlags.ShaderResource, ResourceUsage usage = ResourceUsage.Immutable) { - var texture = Texture.Load(device, stream, flags | TextureFlags.ShaderResource, usage); + var texture = Texture.Load(device, stream, flags, usage); if (!(texture is Texture2D)) throw new ArgumentException(string.Format("Texture is not type of [Texture2D] but [{0}]", texture.GetType().Name)); return (Texture2D)texture; @@ -224,7 +224,7 @@ public static new Texture2D Load(GraphicsDevice device, Stream stream, TextureFl public static new Texture2D Load(GraphicsDevice device, string filePath, TextureFlags flags = TextureFlags.ShaderResource, ResourceUsage usage = ResourceUsage.Immutable) { using (var stream = new NativeFileStream(filePath, NativeFileMode.Open, NativeFileAccess.Read)) - return Load(device, stream, flags | TextureFlags.ShaderResource, usage); + return Load(device, stream, flags, usage); } } } \ No newline at end of file diff --git a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture2DBase.cs b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture2DBase.cs index 3c88d6bb5..d8faad10e 100644 --- a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture2DBase.cs +++ b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture2DBase.cs @@ -18,8 +18,10 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +using System.Collections.Generic; using SharpDX.Direct3D; using SharpDX.Direct3D11; +using SharpDX.DXGI; namespace SharpDX.Toolkit.Graphics { @@ -88,7 +90,7 @@ protected virtual DXGI.Format GetDefaultViewFormat() return this.Description.Format; } - internal override TextureView GetShaderResourceView(ViewType viewType, int arrayOrDepthSlice, int mipIndex) + internal override TextureView GetShaderResourceView(Format viewFormat, ViewType viewType, int arrayOrDepthSlice, int mipIndex) { if ((this.Description.BindFlags & BindFlags.ShaderResource) == 0) return null; @@ -97,17 +99,16 @@ internal override TextureView GetShaderResourceView(ViewType viewType, int array int mipCount; GetViewSliceBounds(viewType, ref arrayOrDepthSlice, ref mipIndex, out arrayCount, out mipCount); - var srvIndex = GetViewIndex(viewType, arrayOrDepthSlice, mipIndex); + var textureViewKey = new TextureViewKey(viewFormat, viewType, arrayOrDepthSlice, mipIndex); lock (this.shaderResourceViews) { - var srv = this.shaderResourceViews[srvIndex]; - + TextureView srv; // Creates the shader resource view - if (srv == null) + if (!shaderResourceViews.TryGetValue(textureViewKey, out srv)) { // Create the view - var srvDescription = new ShaderResourceViewDescription() { Format = GetDefaultViewFormat() }; + var srvDescription = new ShaderResourceViewDescription() { Format = viewFormat }; // Initialize for texture arrays or texture cube if (this.Description.ArraySize > 1) @@ -150,7 +151,7 @@ internal override TextureView GetShaderResourceView(ViewType viewType, int array } srv = new TextureView(this, new ShaderResourceView(this.GraphicsDevice, this.Resource, srvDescription)); - this.shaderResourceViews[srvIndex] = ToDispose(srv); + this.shaderResourceViews.Add(textureViewKey, ToDispose(srv)); } return srv; @@ -213,10 +214,15 @@ protected override void InitializeViews() // Creates the shader resource view if ((this.Description.BindFlags & BindFlags.ShaderResource) != 0) { - this.shaderResourceViews = new TextureView[GetViewCount()]; + this.shaderResourceViews = new Dictionary(); // Pre initialize by default the view on the first array/mipmap - GetShaderResourceView(ViewType.Full, 0, 0); + var viewFormat = GetDefaultViewFormat(); + if(!FormatHelper.IsTypeless(viewFormat)) + { + // Only valid for non-typeless viewformat + defaultShaderResourceView = GetShaderResourceView(viewFormat, ViewType.Full, 0, 0); + } } // Creates the unordered access view diff --git a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture3D.cs b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture3D.cs index ec66adbb3..ec212fd17 100644 --- a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture3D.cs +++ b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture3D.cs @@ -130,7 +130,7 @@ public static Texture3D New(GraphicsDevice device, int width, int height, int de /// ID3D11Device::CreateTexture3D public static Texture3D New(GraphicsDevice device, int width, int height, int depth, MipMapCount mipCount, PixelFormat format, TextureFlags flags = TextureFlags.ShaderResource, ResourceUsage usage = ResourceUsage.Default) { - return new Texture3D(device, NewDescription(width, height, depth, format, flags | TextureFlags.ShaderResource, mipCount, usage)); + return new Texture3D(device, NewDescription(width, height, depth, format, flags, mipCount, usage)); } /// @@ -178,7 +178,7 @@ public static Texture3D New(GraphicsDevice device, int width, int height, int de public static Texture3D New(GraphicsDevice device, int width, int height, int depth, MipMapCount mipCount, PixelFormat format, DataBox[] textureData, TextureFlags flags = TextureFlags.ShaderResource, ResourceUsage usage = ResourceUsage.Default) { // TODO Add check for number of texture data according to width/height/depth/mipCount. - return new Texture3D(device, NewDescription(width, height, depth, format, flags | TextureFlags.ShaderResource, mipCount, usage), textureData); + return new Texture3D(device, NewDescription(width, height, depth, format, flags, mipCount, usage), textureData); } /// @@ -198,7 +198,7 @@ public static Texture3D New(GraphicsDevice device, Image image, TextureFlags fla if (image.Description.Dimension != TextureDimension.Texture3D) throw new ArgumentException("Invalid image. Must be 3D", "image"); - return new Texture3D(device, CreateTextureDescriptionFromImage(image, flags | TextureFlags.ShaderResource, usage), image.ToDataBox()); + return new Texture3D(device, CreateTextureDescriptionFromImage(image, flags, usage), image.ToDataBox()); } /// @@ -212,7 +212,7 @@ public static Texture3D New(GraphicsDevice device, Image image, TextureFlags fla /// A texture public static new Texture3D Load(GraphicsDevice device, Stream stream, TextureFlags flags = TextureFlags.ShaderResource, ResourceUsage usage = ResourceUsage.Immutable) { - var texture = Texture.Load(device, stream, flags | TextureFlags.ShaderResource, usage); + var texture = Texture.Load(device, stream, flags, usage); if (!(texture is Texture3D)) throw new ArgumentException(string.Format("Texture is not type of [Texture3D] but [{0}]", texture.GetType().Name)); return (Texture3D)texture; diff --git a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture3DBase.cs b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture3DBase.cs index e9f0e8436..13a4f1924 100644 --- a/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture3DBase.cs +++ b/Source/Toolkit/SharpDX.Toolkit.Graphics/Texture3DBase.cs @@ -18,8 +18,10 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +using System.Collections.Generic; using SharpDX.Direct3D; using SharpDX.Direct3D11; +using SharpDX.DXGI; namespace SharpDX.Toolkit.Graphics { @@ -85,7 +87,7 @@ public override Texture ToStaging() return new Texture3D(this.GraphicsDevice, this.Description.ToStagingDescription()); } - internal override TextureView GetShaderResourceView(ViewType viewType, int arrayOrDepthSlice, int mipIndex) + internal override TextureView GetShaderResourceView(Format viewFormat, ViewType viewType, int arrayOrDepthSlice, int mipIndex) { if ((this.Description.BindFlags & BindFlags.ShaderResource) == 0) return null; @@ -94,18 +96,17 @@ internal override TextureView GetShaderResourceView(ViewType viewType, int array int mipCount; GetViewSliceBounds(viewType, ref arrayOrDepthSlice, ref mipIndex, out arrayCount, out mipCount); - var srvIndex = GetViewIndex(viewType, arrayOrDepthSlice, mipIndex); + var textureViewKey = new TextureViewKey(viewFormat, viewType, arrayOrDepthSlice, mipIndex); lock (this.shaderResourceViews) { - var srv = this.shaderResourceViews[srvIndex]; - + TextureView srv; // Creates the shader resource view - if (srv == null) + if (!shaderResourceViews.TryGetValue(textureViewKey, out srv)) { // Create the view var srvDescription = new ShaderResourceViewDescription { - Format = this.Description.Format, + Format = viewFormat, Dimension = ShaderResourceViewDimension.Texture3D, Texture3D = { MipLevels = mipCount, @@ -114,7 +115,7 @@ internal override TextureView GetShaderResourceView(ViewType viewType, int array }; srv = new TextureView(this, new ShaderResourceView(this.GraphicsDevice, this.Resource, srvDescription)); - this.shaderResourceViews[srvIndex] = ToDispose(srv); + this.shaderResourceViews.Add(textureViewKey, ToDispose(srv)); } return srv; @@ -161,10 +162,15 @@ protected override void InitializeViews() // Creates the shader resource view if ((this.Description.BindFlags & BindFlags.ShaderResource) != 0) { - this.shaderResourceViews = new TextureView[GetViewCount()]; + shaderResourceViews = new Dictionary(); // Pre initialize by default the view on the first array/mipmap - GetShaderResourceView(ViewType.Full, 0, 0); + var viewFormat = Format; + if (!FormatHelper.IsTypeless(viewFormat)) + { + // Only valid for non-typeless viewformat + defaultShaderResourceView = GetShaderResourceView(viewFormat, ViewType.Full, 0, 0); + } } // Creates the unordered access view