/// <summary>
        /// Creates a new Cube <see cref="Texture" /> from a initial data..
        /// </summary>
        /// <typeparam name="T">Type of a pixel data</typeparam>
        /// <param name="device">The <see cref="GraphicsDevice" />.</param>
        /// <param name="size">The size (in pixels) of the top-level faces of the cube texture.</param>
        /// <param name="format">Describes the format to use.</param>
        /// <param name="textureData">an array of 6 textures. See remarks</param>
        /// <param name="textureFlags">The texture flags.</param>
        /// <param name="usage">The usage.</param>
        /// <returns>A new instance of Cube <see cref="Texture" /> class.</returns>
        /// <exception cref="System.ArgumentException">Invalid texture datas. First dimension must be equal to 6;textureData</exception>
        /// <remarks>The first dimension of mipMapTextures describes the number of array (TextureCube Array), the second is the texture data for a particular cube face.</remarks>
        public unsafe static Texture NewCube <T>(GraphicsDevice device, int size, PixelFormat format, T[][] textureData, TextureFlags textureFlags = TextureFlags.ShaderResource, GraphicsResourceUsage usage = GraphicsResourceUsage.Immutable) where T : struct
        {
            if (textureData.Length != 6)
            {
                throw new ArgumentException("Invalid texture datas. First dimension must be equal to 6", "textureData");
            }

            var dataBoxes = new DataBox[6];

            dataBoxes[0] = GetDataBox(format, size, size, 1, textureData[0], (IntPtr)Interop.Fixed(textureData[0]));
            dataBoxes[1] = GetDataBox(format, size, size, 1, textureData[0], (IntPtr)Interop.Fixed(textureData[1]));
            dataBoxes[2] = GetDataBox(format, size, size, 1, textureData[0], (IntPtr)Interop.Fixed(textureData[2]));
            dataBoxes[3] = GetDataBox(format, size, size, 1, textureData[0], (IntPtr)Interop.Fixed(textureData[3]));
            dataBoxes[4] = GetDataBox(format, size, size, 1, textureData[0], (IntPtr)Interop.Fixed(textureData[4]));
            dataBoxes[5] = GetDataBox(format, size, size, 1, textureData[0], (IntPtr)Interop.Fixed(textureData[5]));

            return(new Texture(device).InitializeFrom(TextureDescription.NewCube(size, format, textureFlags, usage), dataBoxes));
        }
 internal unsafe void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region)
 {
     if (resource == null)
     {
         throw new ArgumentNullException("resource");
     }
     NativeDeviceContext.UpdateSubresource(*(SharpDX.DataBox *)Interop.Cast(ref databox), resource.NativeResource, subResourceIndex, *(SharpDX.Direct3D11.ResourceRegion *)Interop.Cast(ref region));
 }
 internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region)
 {
     NullHelper.ToImplement();
 }
        internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region)
        {
            var texture = resource as Texture;

            if (texture != null)
            {
                var width  = region.Right - region.Left;
                var height = region.Bottom - region.Top;
                var depth  = region.Back - region.Front;

                ResourceDescription resourceDescription;
                switch (texture.Dimension)
                {
                case TextureDimension.Texture1D:
                    resourceDescription = ResourceDescription.Texture1D((SharpDX.DXGI.Format)texture.Format, width, 1, 1);
                    break;

                case TextureDimension.Texture2D:
                case TextureDimension.TextureCube:
                    resourceDescription = ResourceDescription.Texture2D((SharpDX.DXGI.Format)texture.Format, width, height, 1, 1);
                    break;

                case TextureDimension.Texture3D:
                    resourceDescription = ResourceDescription.Texture3D((SharpDX.DXGI.Format)texture.Format, width, height, (short)depth, 1);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                // TODO D3D12 allocate in upload heap (placed resources?)
                var nativeUploadTexture = NativeDevice.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None,
                                                                               resourceDescription,
                                                                               ResourceStates.GenericRead);


                GraphicsDevice.TemporaryResources.Enqueue(new KeyValuePair <long, Pageable>(GraphicsDevice.NextFenceValue, nativeUploadTexture));

                nativeUploadTexture.WriteToSubresource(0, null, databox.DataPointer, databox.RowPitch, databox.SlicePitch);

                var parentResource = resource.ParentResource ?? resource;

                // Trigger copy
                NativeCommandList.ResourceBarrierTransition(resource.NativeResource, parentResource.NativeResourceState, ResourceStates.CopyDestination);
                NativeCommandList.CopyTextureRegion(new TextureCopyLocation(resource.NativeResource, subResourceIndex), region.Left, region.Top, region.Front, new TextureCopyLocation(nativeUploadTexture, 0), null);
                NativeCommandList.ResourceBarrierTransition(resource.NativeResource, ResourceStates.CopyDestination, parentResource.NativeResourceState);
            }
            else
            {
                var buffer = resource as Buffer;
                if (buffer != null)
                {
                    SharpDX.Direct3D12.Resource uploadResource;
                    int uploadOffset;
                    var uploadSize   = region.Right - region.Left;
                    var uploadMemory = GraphicsDevice.AllocateUploadBuffer(region.Right - region.Left, out uploadResource, out uploadOffset);

                    Utilities.CopyMemory(uploadMemory, databox.DataPointer, uploadSize);

                    NativeCommandList.ResourceBarrierTransition(resource.NativeResource, resource.NativeResourceState, ResourceStates.CopyDestination);
                    NativeCommandList.CopyBufferRegion(resource.NativeResource, region.Left, uploadResource, uploadOffset, uploadSize);
                    NativeCommandList.ResourceBarrierTransition(resource.NativeResource, ResourceStates.CopyDestination, resource.NativeResourceState);
                }
                else
                {
                    throw new InvalidOperationException("Unknown resource type");
                }
            }
        }
        internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox)
        {
            ResourceRegion region;
            var            texture = resource as Texture;

            if (texture != null)
            {
                region = new ResourceRegion(0, 0, 0, texture.Width, texture.Height, texture.Depth);
            }
            else
            {
                var buffer = resource as Buffer;
                if (buffer != null)
                {
                    region = new ResourceRegion(0, 0, 0, buffer.SizeInBytes, 1, 1);
                }
                else
                {
                    throw new InvalidOperationException("Unknown resource type");
                }
            }

            UpdateSubresource(resource, subResourceIndex, databox, region);
        }
        internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region)
        {
            var texture = resource as Texture;

            if (texture != null)
            {
                if (texture.Dimension != TextureDimension.Texture2D)
                {
                    throw new NotImplementedException();
                }

                var width  = region.Right - region.Left;
                var height = region.Bottom - region.Top;

                // TODO D3D12 allocate in upload heap (placed resources?)
                var nativeUploadTexture = NativeDevice.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None,
                                                                               ResourceDescription.Texture2D((SharpDX.DXGI.Format)texture.Format, width, height),
                                                                               ResourceStates.GenericRead);

                GraphicsDevice.TemporaryResources.Enqueue(new KeyValuePair <long, Pageable>(GraphicsDevice.NextFenceValue, nativeUploadTexture));

                nativeUploadTexture.WriteToSubresource(0, null, databox.DataPointer, databox.RowPitch, databox.SlicePitch);

                var parentResource = resource.ParentResource ?? resource;

                // Trigger copy
                NativeCommandList.ResourceBarrierTransition(resource.NativeResource, parentResource.NativeResourceState, ResourceStates.CopyDestination);
                NativeCommandList.CopyTextureRegion(new TextureCopyLocation(resource.NativeResource, subResourceIndex), region.Left, region.Top, region.Front, new TextureCopyLocation(nativeUploadTexture, 0), null);
                NativeCommandList.ResourceBarrierTransition(resource.NativeResource, ResourceStates.CopyDestination, parentResource.NativeResourceState);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
 internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox)
 {
     throw new NotImplementedException();
 }
Exemple #8
0
        private void InitializeFromImpl(DataBox[] dataBoxes = null)
        {
            if (ParentTexture != null)
            {
                TextureId = ParentTexture.TextureId;

                // copy parameters
                TextureInternalFormat = ParentTexture.TextureInternalFormat;
                TextureFormat         = ParentTexture.TextureFormat;
                TextureType           = ParentTexture.TextureType;
                TextureTarget         = ParentTexture.TextureTarget;
                DepthPitch            = ParentTexture.DepthPitch;
                RowPitch       = ParentTexture.RowPitch;
                IsDepthBuffer  = ParentTexture.IsDepthBuffer;
                HasStencil     = ParentTexture.HasStencil;
                IsRenderbuffer = ParentTexture.IsRenderbuffer;

                stencilId           = ParentTexture.StencilId;
                pixelBufferObjectId = ParentTexture.PixelBufferObjectId;
            }

            if (TextureId == 0)
            {
                switch (Dimension)
                {
                case TextureDimension.Texture1D:
#if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    if (ArraySize > 1)
                    {
                        throw new PlatformNotSupportedException("Texture1DArray is not implemented under OpenGL");
                    }
                    TextureTarget = TextureTarget.Texture1D;
                    break;
#endif
                case TextureDimension.Texture2D:
                    TextureTarget = ArraySize > 1 ? TextureTarget.Texture2DArray : TextureTarget.Texture2D;
                    break;

                case TextureDimension.Texture3D:
                    TextureTarget = TextureTarget.Texture3D;
                    break;

                case TextureDimension.TextureCube:
                    if (ArraySize > 6)
                    {
                        throw new PlatformNotSupportedException("TextureCubeArray is not implemented under OpenGL");
                    }
                    TextureTarget = TextureTarget.TextureCubeMap;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                bool compressed;
                OpenGLConvertExtensions.ConvertPixelFormat(GraphicsDevice, ref textureDescription.Format, out TextureInternalFormat, out TextureFormat, out TextureType, out TexturePixelSize, out compressed);

                DepthPitch = Description.Width * Description.Height * TexturePixelSize;
                RowPitch   = Description.Width * TexturePixelSize;

                if ((Description.Flags & TextureFlags.DepthStencil) != 0)
                {
                    IsDepthBuffer = true;
                    HasStencil    = InternalHasStencil(Format);
                }
                else
                {
                    IsDepthBuffer = false;
                    HasStencil    = false;
                }

                if ((Description.Flags & TextureFlagsCustomResourceId) != 0)
                {
                    return;
                }

                using (var openglContext = GraphicsDevice.UseOpenGLCreationContext())
                {
                    // Depth texture are render buffer for now
                    // TODO: enable switch
                    if ((Description.Flags & TextureFlags.DepthStencil) != 0 && (Description.Flags & TextureFlags.ShaderResource) == 0)
                    {
                        RenderbufferStorage depth, stencil;
                        ConvertDepthFormat(GraphicsDevice, Description.Format, out depth, out stencil);

                        GL.GenRenderbuffers(1, out TextureId);
                        GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, TextureId);
                        GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, depth, Width, Height);

                        if (stencil != 0)
                        {
                            // separate stencil
                            GL.GenRenderbuffers(1, out stencilId);
                            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, stencilId);
                            GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, stencil, Width, Height);
                        }
                        else if (HasStencil)
                        {
                            // depth+stencil in a single texture
                            stencilId = TextureId;
                        }

                        GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0);

                        IsRenderbuffer = true;
                        return;
                    }

                    IsRenderbuffer = false;

                    TextureTotalSize = ComputeBufferTotalSize();

                    if (Description.Usage == GraphicsResourceUsage.Staging)
                    {
                        InitializeStagingPixelBufferObject(dataBoxes);
                        return;
                    }

                    GL.GenTextures(1, out TextureId);
                    GL.BindTexture(TextureTarget, TextureId);

                    // No filtering on depth buffer
                    if ((Description.Flags & (TextureFlags.RenderTarget | TextureFlags.DepthStencil)) != TextureFlags.None)
                    {
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
                        BoundSamplerState = GraphicsDevice.SamplerStates.PointClamp;

                        if (HasStencil)
                        {
                            // depth+stencil in a single texture
                            stencilId = TextureId;
                        }
                    }
#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    else if (Description.MipLevels <= 1)
                    {
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                    }
#endif

#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    if (!GraphicsDevice.IsOpenGLES2)
#endif
                    {
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureBaseLevel, 0);
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureMaxLevel, Description.MipLevels - 1);
                    }

                    if (Description.MipLevels == 0)
                    {
                        throw new NotImplementedException();
                    }

                    var setSize = TextureSetSize(TextureTarget);

                    for (var arrayIndex = 0; arrayIndex < Description.ArraySize; ++arrayIndex)
                    {
                        var offsetArray = arrayIndex * Description.MipLevels;
                        for (int i = 0; i < Description.MipLevels; ++i)
                        {
                            DataBox dataBox;
                            var     width  = CalculateMipSize(Description.Width, i);
                            var     height = CalculateMipSize(Description.Height, i);
                            var     depth  = CalculateMipSize(Description.Depth, i);
                            if (dataBoxes != null && i < dataBoxes.Length)
                            {
                                if (setSize > 1 && !compressed && dataBoxes[i].RowPitch != width * TexturePixelSize)
                                {
                                    throw new NotSupportedException("Can't upload texture with pitch in glTexImage2D/3D.");
                                }
                                // Might be possible, need to check API better.
                                dataBox = dataBoxes[offsetArray + i];
                            }
                            else
                            {
                                dataBox = new DataBox();
                            }

                            switch (TextureTarget)
                            {
#if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                            case TextureTarget.Texture1D:
                                if (compressed)
                                {
                                    GL.CompressedTexImage1D(TextureTarget, i, TextureInternalFormat, width, 0, dataBox.SlicePitch, dataBox.DataPointer);
                                }
                                else
                                {
                                    GL.TexImage1D(TextureTarget, i, TextureInternalFormat, width, 0, TextureFormat, TextureType, dataBox.DataPointer);
                                }
                                break;
#endif
                            case TextureTarget.Texture2D:
                            case TextureTarget.TextureCubeMap:
                            {
                                var dataSetTarget = GetTextureTargetForDataSet2D(TextureTarget, arrayIndex);
                                if (compressed)
                                {
                                    GL.CompressedTexImage2D(dataSetTarget, i, (CompressedInternalFormat2D)TextureInternalFormat, width, height, 0, dataBox.SlicePitch, dataBox.DataPointer);
                                }
                                else
                                {
                                    GL.TexImage2D(dataSetTarget, i, (TextureComponentCount2D)TextureInternalFormat, width, height, 0, TextureFormat, TextureType, dataBox.DataPointer);
                                }
                                break;
                            }

                            case TextureTarget.Texture3D:
                            {
                                if (compressed)
                                {
                                    GL.CompressedTexImage3D((TextureTarget3d)TextureTarget, i, (CompressedInternalFormat3D)TextureInternalFormat, width, height, depth, 0, dataBox.SlicePitch, dataBox.DataPointer);
                                }
                                else
                                {
                                    GL.TexImage3D((TextureTarget3d)TextureTarget, i, (TextureComponentCount3D)TextureInternalFormat, width, height, depth, 0, TextureFormat, TextureType, dataBox.DataPointer);
                                }
                                break;
                            }

                            case TextureTarget.Texture2DArray:
                            {
                                // We create all array slices at once, but upload them one by one
                                if (arrayIndex == 0)
                                {
                                    if (compressed)
                                    {
                                        GL.CompressedTexImage3D((TextureTarget3d)TextureTarget, i, (CompressedInternalFormat3D)TextureInternalFormat, width, height, ArraySize, 0, 0, IntPtr.Zero);
                                    }
                                    else
                                    {
                                        GL.TexImage3D((TextureTarget3d)TextureTarget, i, (TextureComponentCount3D)TextureInternalFormat, width, height, ArraySize, 0, TextureFormat, TextureType, IntPtr.Zero);
                                    }
                                }

                                if (dataBox.DataPointer != IntPtr.Zero)
                                {
                                    if (compressed)
                                    {
                                        GL.CompressedTexSubImage3D((TextureTarget3d)TextureTarget, i, 0, 0, arrayIndex, width, height, 1, TextureFormat, dataBox.SlicePitch, dataBox.DataPointer);
                                    }
                                    else
                                    {
                                        GL.TexSubImage3D((TextureTarget3d)TextureTarget, i, 0, 0, arrayIndex, width, height, 1, TextureFormat, TextureType, dataBox.DataPointer);
                                    }
                                }
                                break;
                            }
                            }
                        }
                    }
                    GL.BindTexture(TextureTarget, 0);
                    if (openglContext.CommandList != null)
                    {
                        // If we messed up with some states of a command list, mark dirty states
                        openglContext.CommandList.boundShaderResourceViews[openglContext.CommandList.activeTexture] = null;
                    }
                }

                GraphicsDevice.TextureMemory += (Depth * DepthStride) / (float)0x100000;
            }
        }