static unsafe void Reset(MyGeneratedTexture tex, byte[] data, int nchannels) { if (data == null) { tex.Reset(null); } else { fixed(byte *dptr = data) { int numMiplevels = tex.NumMipLevels; DataBox[] dataBox = new DataBox[numMiplevels]; int width = tex.Size.X; int height = tex.Size.Y; int offset = 0; for (int i = 0; i < numMiplevels; ++i) { dataBox[i].DataPointer = new IntPtr(dptr + offset); dataBox[i].RowPitch = width * nchannels; offset += width * height * nchannels; width >>= 1; height >>= 1; } tex.Reset(dataBox); } } }
public void Update(IIndexBuffer buffer, DataArray data, int count) { var dxBuffer = graphicsDevice.Cast <IndexBuffer>(buffer, "buffer"); if (dxBuffer.Usage == ResourceUsage.Immutable) { throw new ArgumentException("Can't update immutable resource.", "buffer"); } if (data.Size != buffer.SizeBytes) { throw new ArgumentException("Data does not match IndexBuffer size.", "data"); } if (dxBuffer.Usage == ResourceUsage.Normal) { renderContext.Context.UpdateSubresource(new SharpDX.DataBox(data.Pointer, 0, 0), dxBuffer.Buffer); } else { MapMode mapMode = dxBuffer.Usage == ResourceUsage.Dynamic ? MapMode.WriteDiscard : MapMode.Write; SharpDX.DataBox box = renderContext.Context.MapSubresource(dxBuffer.Buffer, 0, mapMode, MapFlags.None); SharpDX.Utilities.CopyMemory(box.DataPointer, data.Pointer, data.Size); renderContext.Context.UnmapSubresource(dxBuffer.Buffer, 0); } }
private void PlatformSetData <T>(int level, Rectangle?rect, T[] data, int startIndex, int elementCount) where T : struct { var elementSizeInByte = Marshal.SizeOf(typeof(T)); var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); // Use try..finally to make sure dataHandle is freed in case of an error try { var startBytes = startIndex * elementSizeInByte; var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes); int x, y, w, h; if (rect.HasValue) { x = rect.Value.X; y = rect.Value.Y; w = rect.Value.Width; h = rect.Value.Height; } else { x = 0; y = 0; w = Math.Max(width >> level, 1); h = Math.Max(height >> level, 1); // For DXT textures the width and height of each level is a multiple of 4. // OpenGL only: The last two mip levels require the width and height to be // passed as 2x2 and 1x1, but there needs to be enough data passed to occupy // a 4x4 block. // Ref: http://www.mentby.com/Group/mac-opengl/issue-with-dxt-mipmapped-textures.html if (_format == SurfaceFormat.Dxt1 || _format == SurfaceFormat.Dxt1a || _format == SurfaceFormat.Dxt3 || _format == SurfaceFormat.Dxt5) { w = (w + 3) & ~3; h = (h + 3) & ~3; } } var box = new SharpDX.DataBox(dataPtr, GetPitch(w), 0); var region = new SharpDX.Direct3D11.ResourceRegion(); region.Top = y; region.Front = 0; region.Back = 1; region.Bottom = y + h; region.Left = x; region.Right = x + w; // TODO: We need to deal with threaded contexts here! var d3dContext = GraphicsDevice._d3dContext; lock (d3dContext) d3dContext.UpdateSubresource(box, GetTexture(), level, region); } finally { dataHandle.Free(); } }
/// <summary> /// Triggers internal rendering within the resource (e. g. Render to Texture). /// </summary> /// <param name="renderState">Current render state.</param> public void Render(RenderState renderState) { D3D11.DeviceContext deviceContext = renderState.Device.DeviceImmediateContextD3D11; // Upload the last read video frame to texture buffer on the graphics device if (m_thumbnailFrame != null) { SharpDX.DataBox dataBox = deviceContext.MapSubresource(m_texture, 0, D3D11.MapMode.WriteDiscard, D3D11.MapFlags.None); try { unsafe { int *frameBufferPointerNative = (int *)m_thumbnailFrame.Pointer.ToPointer(); int *textureBufferPointerNative = (int *)dataBox.DataPointer.ToPointer(); // Performance optimization using MemCopy // see http://www.rolandk.de/wp/2015/05/wie-schnell-man-speicher-falsch-kopieren-kann/ for (int loopY = 0; loopY < m_videoHeight; loopY++) { IntPtr rowStartTexture = new IntPtr(textureBufferPointerNative + (dataBox.RowPitch / 4) * loopY); IntPtr rowStartSource = new IntPtr(frameBufferPointerNative + (m_videoWidth) * loopY); CommonTools.CopyMemory(rowStartSource, rowStartTexture, (ulong)dataBox.RowPitch); } } } finally { GraphicsHelper.SafeDispose(ref m_thumbnailFrame); deviceContext.UnmapSubresource(m_texture, 0); } } }
public unsafe override void UpdateBuffer(Buffer buffer, uint bufferOffsetInBytes, IntPtr source, uint sizeInBytes) { D3D11Buffer d3dBuffer = Util.AssertSubtype <Buffer, D3D11Buffer>(buffer); if (sizeInBytes == 0) { return; } bool useMap = (buffer.Usage & BufferUsage.Dynamic) == BufferUsage.Dynamic; if (useMap) { if (bufferOffsetInBytes != 0) { throw new NotImplementedException("bufferOffsetInBytes must be 0 for Dynamic Buffers."); } SharpDX.DataBox db = _context.MapSubresource( d3dBuffer.Buffer, 0, SharpDX.Direct3D11.MapMode.WriteDiscard, MapFlags.None); if (sizeInBytes < 1024) { Unsafe.CopyBlock(db.DataPointer.ToPointer(), source.ToPointer(), sizeInBytes); } else { System.Buffer.MemoryCopy(source.ToPointer(), db.DataPointer.ToPointer(), buffer.SizeInBytes, sizeInBytes); } _context.UnmapSubresource(d3dBuffer.Buffer, 0); } else { ResourceRegion?subregion = null; if ((d3dBuffer.Buffer.Description.BindFlags & BindFlags.ConstantBuffer) != BindFlags.ConstantBuffer) { // For a shader-constant buffer; set pDstBox to null. It is not possible to use // this method to partially update a shader-constant buffer subregion = new ResourceRegion() { Left = (int)bufferOffsetInBytes, Right = (int)(sizeInBytes + bufferOffsetInBytes), Bottom = 1, Back = 1 }; } if (bufferOffsetInBytes == 0) { _context.UpdateSubresource(d3dBuffer.Buffer, 0, subregion, source, 0, 0); } else { _context1.UpdateSubresource1(d3dBuffer.Buffer, 0, subregion, source, 0, 0, 0); } } }
internal TextureArray(Device device, int width, int height, int[][][] pixels) { this.device = device; Width = width; Height = height; int mipsCount = pixels[0].Length; int texturesCount = pixels.Length; int[][] rawDatas = new int[mipsCount][]; SharpDX.DataBox[] boxes = new SharpDX.DataBox[texturesCount * mipsCount]; unsafe { for (int j = 0; j < texturesCount; ++j) { width = Width; height = Height; for (int i = 0; i < mipsCount; ++i) { fixed(int *p = pixels[j][i]) { IntPtr pp = (IntPtr)p; boxes[j * mipsCount + i] = new SharpDX.DataBox(pp, width * 4, width * height * 4); } width /= 2; height /= 2; } } } texture = new Texture2D(device, new Texture2DDescription() { Width = Width, Height = Height, ArraySize = texturesCount, BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget, Usage = ResourceUsage.Default, CpuAccessFlags = CpuAccessFlags.None, Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm, MipLevels = mipsCount, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), }, boxes); ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription() { Format = texture.Description.Format, Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2DArray, }; srvDesc.Texture2DArray.MostDetailedMip = 0; srvDesc.Texture2DArray.MipLevels = -1; srvDesc.Texture2DArray.ArraySize = texturesCount; srvDesc.Texture2DArray.FirstArraySlice = 0; TextureResource = new ShaderResourceView(device, texture, srvDesc); }
public T[] ReadData(int count) { SharpDX.DataStream stream; SharpDX.DataBox box = _d3dContext.MapSubresource(_resultBuffer, 0, MapMode.Read, MapFlags.None, out stream); T[] result = stream.ReadRange <T>(count); _d3dContext.UnmapSubresource(_buffer, 0); return(result); }
/// <summary> /// Saves the contents of a <see cref="SharpDX.Direct3D11.Texture2D"/> to a file with name contained in <paramref name="filename"/> using the specified <see cref="System.Drawing.Imaging.ImageFormat"/>. /// </summary> /// <param name="texture">The <see cref="SharpDX.Direct3D11.Texture2D"/> containing the data to save.</param> /// <param name="filename">The filename on disk where the output image should be saved.</param> /// <param name="imageFormat">The format to use when saving the output file.</param> public void SaveTextureToFile(SharpDX.Direct3D11.Texture2D texture, string filename, System.Drawing.Imaging.ImageFormat imageFormat) { // If the existing debug texture doesn't exist, or the incoming texture is different than the existing debug texture... if (m_pDebugTexture == null || !TextureCanBeCopied(m_pDebugTexture, texture)) { // Dispose of any existing texture if (m_pDebugTexture != null) { m_pDebugTexture.Dispose(); } // Copy the original texture's description... SharpDX.Direct3D11.Texture2DDescription newDescription = texture.Description; // Then modify the parameters to create a CPU-readable staging texture newDescription.BindFlags = SharpDX.Direct3D11.BindFlags.None; newDescription.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.Read; newDescription.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None; newDescription.Usage = SharpDX.Direct3D11.ResourceUsage.Staging; // Re-generate the debug texture by copying the new texture's description m_pDebugTexture = new SharpDX.Direct3D11.Texture2D(m_pDevice, newDescription); } // Copy the texture to our debug texture m_pDevice.ImmediateContext.CopyResource(texture, m_pDebugTexture); // Map the debug texture's resource 0 for read mode SharpDX.DataStream data; SharpDX.DataBox dbox = m_pDevice.ImmediateContext.MapSubresource(m_pDebugTexture, 0, 0, SharpDX.Direct3D11.MapMode.Read, SharpDX.Direct3D11.MapFlags.None, out data); // Create a bitmap that's the same size as the debug texture Bitmap b = new Bitmap(m_pDebugTexture.Description.Width, m_pDebugTexture.Description.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb); // Lock the bitmap data to get access to the native bitmap pointer System.Drawing.Imaging.BitmapData bd = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); // Use the native pointers to do a native-to-native memory copy from the mapped subresource to the bitmap data // WARNING: This might totally blow up if you're using a different color format than B8G8R8A8_UNorm, I don't know how planar formats are structured as D3D textures! // // You can use Win32 CopyMemory to do the below copy if need be, but you have to do it in a loop to respect the Stride and RowPitch parameters in case the texture width // isn't on an aligned byte boundary. MediaFoundation.MFExtern.MFCopyImage(bd.Scan0, bd.Stride, dbox.DataPointer, dbox.RowPitch, bd.Width * 4, bd.Height); /// Unlock the bitmap b.UnlockBits(bd); // Unmap the subresource mapping, ignore the SharpDX.DataStream because we don't need it. m_pDevice.ImmediateContext.UnmapSubresource(m_pDebugTexture, 0); data = null; // Save the bitmap to the desired filename b.Save(filename, imageFormat); b.Dispose(); b = null; }
//SharpDX.DataBox src = context.MapSubresource(lightDataBuffer, 1, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out SharpDX.DataStream stream); //stream.Write(light.GetStructLayoutResource()); //context.UnmapSubresource(lightDataBuffer, LightStructLayout.RegisterResourceSlot); public void UpdateDynamicBuffer <T>(T[] newdata, SharpDX.Direct3D11.Buffer buffer, int slot) where T : struct { SharpDX.DataStream stream = null; try { SharpDX.DataBox src = ImmediateContext.MapSubresource(buffer, slot, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream); stream.WriteRange(newdata); ImmediateContext.UnmapSubresource(buffer, slot); } finally { } }
public T[] GetData <T>(int count) where T : struct { _deviceContext.CopyResource(_buffer, _resultBuffer); SharpDX.DataStream stream; SharpDX.DataBox box = _deviceContext.MapSubresource(_resultBuffer, 0, MapMode.Read, MapFlags.None, out stream); T[] result = stream.ReadRange <T>(count); _deviceContext.UnmapSubresource(_buffer, 0); return(result); }
protected internal void Reset(DataBox[] dataBoxes) { Dispose(); if (dataBoxes == null) m_resource = new Texture2D(MyRender11.Device, m_desc); else m_resource = new Texture2D(MyRender11.Device, m_desc, dataBoxes); m_resource.DebugName = m_name; m_srv = new ShaderResourceView(MyRender11.Device, m_resource); m_srv.DebugName = m_name; }
private void PlatformSetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct { GenerateIfRequired(); if (_isDynamic) { // We assume discard by default. var mode = SharpDX.Direct3D11.MapMode.WriteDiscard; if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite) { mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite; } var d3dContext = GraphicsDevice._d3dContext; lock (d3dContext) { var dataBox = d3dContext.MapSubresource(_buffer, 0, mode, SharpDX.Direct3D11.MapFlags.None); SharpDX.Utilities.Write(IntPtr.Add(dataBox.DataPointer, offsetInBytes), data, startIndex, elementCount); d3dContext.UnmapSubresource(_buffer, 0); } } else { var elementSizeInBytes = ReflectionHelpers.SizeOf <T> .Get(); var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); try { var startBytes = startIndex * elementSizeInBytes; var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes); var box = new SharpDX.DataBox(dataPtr, elementCount * elementSizeInBytes, 0); var region = new SharpDX.Direct3D11.ResourceRegion(); region.Top = 0; region.Front = 0; region.Back = 1; region.Bottom = 1; region.Left = offsetInBytes; region.Right = offsetInBytes + (elementCount * elementSizeInBytes); // TODO: We need to deal with threaded contexts here! var d3dContext = GraphicsDevice._d3dContext; lock (d3dContext) d3dContext.UpdateSubresource(box, _buffer, 0, region); } finally { dataHandle.Free(); } } }
//SharpDX.DataBox src = context.MapSubresource(lightDataBuffer, 1, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out SharpDX.DataStream stream); //stream.Write(light.GetStructLayoutResource()); //context.UnmapSubresource(lightDataBuffer, LightStructLayout.RegisterResourceSlot); public void UpdateDynamicBuffer <T>(T[] newdata, SharpDX.Direct3D11.Buffer buffer) where T : struct { SharpDX.DataStream stream = null; try { SharpDX.DataBox src = ImmediateContext.MapSubresource(buffer, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream); // src.DataPointer stream.WriteRange(newdata); } finally { // Every buffer is defined as a single subresource (unlike textures). So subresource is always equals 0. ImmediateContext.UnmapSubresource(buffer, 0); } }
internal unsafe static SharpDX.DataBox[] ConvertDataBoxes(DataBox[] dataBoxes) { if (dataBoxes == null || dataBoxes.Length == 0) { return(null); } var sharpDXDataBoxes = new SharpDX.DataBox[dataBoxes.Length]; fixed(void *pDataBoxes = sharpDXDataBoxes) Utilities.Write((IntPtr)pDataBoxes, dataBoxes, 0, dataBoxes.Length); return(sharpDXDataBoxes); }
/// <summary> /// Maps a subresource. /// </summary> /// <param name="resource">The resource.</param> /// <param name="subResourceIndex">Index of the sub resource.</param> /// <param name="mapMode">The map mode.</param> /// <param name="doNotWait">if set to <c>true</c> this method will return immediately if the resource is still being used by the GPU for writing. Default is false</param> /// <param name="offsetInBytes">The offset information in bytes.</param> /// <param name="lengthInBytes">The length information in bytes.</param> /// <returns>Pointer to the sub resource to map.</returns> public unsafe MappedResource MapSubresource(GraphicsResource resource, int subResourceIndex, MapMode mapMode, bool doNotWait = false, int offsetInBytes = 0, int lengthInBytes = 0) { if (resource == null) { throw new ArgumentNullException("resource"); } SharpDX.DataBox dataBox = NativeDeviceContext.MapSubresource(resource.NativeResource, subResourceIndex, (SharpDX.Direct3D11.MapMode)mapMode, doNotWait ? SharpDX.Direct3D11.MapFlags.DoNotWait : SharpDX.Direct3D11.MapFlags.None); var databox = *(DataBox *)Interop.Cast(ref dataBox); if (!dataBox.IsEmpty) { databox.DataPointer = (IntPtr)((byte *)databox.DataPointer + offsetInBytes); } return(new MappedResource(resource, subResourceIndex, databox)); }
public override ImageCapture CaptureRenderTarget(RenderTarget surface) { IntPtr texNativePtr = RenderDeviceD3D11.GetTextureNativePointer(surface.Texture); ShaderResourceView view = new ShaderResourceView(texNativePtr); using (Texture2D source = view.Resource.QueryInterface <Texture2D>()) { Texture2DDescription desc = source.Description; desc.CpuAccessFlags = CpuAccessFlags.Read; desc.Usage = ResourceUsage.Staging; desc.BindFlags = BindFlags.None; using (Texture2D dest = new Texture2D(_dev, desc)) { _dev.ImmediateContext.CopyResource(source, dest); SharpDX.DataBox data = _dev.ImmediateContext.MapSubresource(dest, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None); if (_imageCapture == null || _imageCapture.Width != desc.Width || _imageCapture.Height != desc.Height) { _imageCapture = new ImageCapture((uint)desc.Width, (uint)desc.Height); } byte[] dst = _imageCapture.Pixels; IntPtr src = data.DataPointer; for (int i = 0; i < desc.Height; ++i) { int dstRow = i * (int)_imageCapture.Stride; int srcRow = i * data.RowPitch; for (int j = 0; j < desc.Width; j++) { // RGBA -> BGRA dst[dstRow + 4 * j + 2] = Noesis.Marshal.ReadByte(src, srcRow + 4 * j + 0); dst[dstRow + 4 * j + 1] = Noesis.Marshal.ReadByte(src, srcRow + 4 * j + 1); dst[dstRow + 4 * j + 0] = Noesis.Marshal.ReadByte(src, srcRow + 4 * j + 2); dst[dstRow + 4 * j + 3] = Noesis.Marshal.ReadByte(src, srcRow + 4 * j + 3); } } _dev.ImmediateContext.UnmapSubresource(dest, 0); } } return(_imageCapture); }
/// <summary> /// Triggers internal rendering within the resource (e. g. Render to Texture). /// </summary> /// <param name="renderState">Current render state.</param> public void Render(RenderState renderState) { D3D11.DeviceContext deviceContext = renderState.Device.DeviceImmediateContextD3D11; // Do nothing here if we have no new frame to render if (m_lastFrameTimestamp >= m_videoReader.CurrentFrameTimestamp) { return; } // Upload the last read video frame to texture buffer on the graphics device using (SeeingSharpMediaBuffer mediaBuffer = m_videoReader.GetCurrentFrame()) { MF.MediaBuffer mediaBufferNative = mediaBuffer.GetBuffer(); SharpDX.DataBox dataBox = deviceContext.MapSubresource(m_texture, 0, D3D11.MapMode.WriteDiscard, D3D11.MapFlags.None); try { int cbMaxLength; int cbCurrentLenght; IntPtr mediaBufferPointer = mediaBufferNative.Lock(out cbMaxLength, out cbCurrentLenght); try { unsafe { int *frameBufferPointerNative = (int *)mediaBufferPointer.ToPointer(); int *textureBufferPointerNative = (int *)dataBox.DataPointer.ToPointer(); // Performance optimization using MemCopy // see http://www.rolandk.de/wp/2015/05/wie-schnell-man-speicher-falsch-kopieren-kann/ for (int loopY = 0; loopY < m_currentHeight; loopY++) { IntPtr rowStartTexture = new IntPtr(textureBufferPointerNative + (dataBox.RowPitch / 4) * loopY); IntPtr rowStartSource = new IntPtr(frameBufferPointerNative + (m_currentWidth) * loopY); CommonTools.CopyMemory(rowStartSource, rowStartTexture, (ulong)dataBox.RowPitch); } } } finally { mediaBufferNative.Unlock(); } } finally { deviceContext.UnmapSubresource(m_texture, 0); } } }
internal static Texture2D TextureCube(DeviceResources deviceResources, SharpDX.DataStream stream, SharpDX.Size2 size) { var arraySize = 6; var textDesc = TextureDescription(arraySize, size.Width, size.Height, ResourceOptionFlags.TextureCube); var stride = size.Width * 4; var dataRects = new SharpDX.DataBox[arraySize]; for (var i = 0; i < arraySize; i++) { dataRects[i] = new SharpDX.DataBox(stream.DataPointer, stride, 0); } var texture2D = new Texture2D(deviceResources.D3DDevice, textDesc, dataRects); return(texture2D); }
public void Init(string name, Texture2DDescription desc, DataBox[] dataBoxes, Vector2I size, int bytes, bool enableDxInitialisation) { Clear(); m_name = name; m_size = size; m_desc = desc; m_bytes = bytes; if (enableDxInitialisation) { m_resource = new Texture2D(MyRender11.Device, m_desc, dataBoxes); m_resource.DebugName = name; m_srv = new ShaderResourceView(MyRender11.Device, m_resource); m_srv.DebugName = name; } }
private void UploadTextureData(Renderer renderer) { if (_textureIsDirty.Get(renderer)) { _textureIsDirty.Set(renderer, false); var tex = _texture.Get(renderer); // upload level 0 SharpDX.DataBox box = new SharpDX.DataBox(); box.SlicePitch = 0; if (_dataBuffer.Get(renderer) != null) { // upload from byte array box.RowPitch = _dataBufferRowPitch.Get(renderer); GCHandle dataHandle = GCHandle.Alloc(_dataBuffer.Get(renderer), GCHandleType.Pinned); box.DataPointer = Marshal.UnsafeAddrOfPinnedArrayElement(_dataBuffer.Get(renderer), _dataBufferOffset.Get(renderer)); renderer.DeviceContext.UpdateSubresource(box, tex, 0); dataHandle.Free(); } else if (_dataStream != null) { // upload from data stream lock (_dataStream) { box.RowPitch = _dataStreamRowPitch; _dataStream.Position = 0; box.DataPointer = _dataStream.DataPointer; renderer.DeviceContext.UpdateSubresource(box, tex, 0); } } else { return; } if (AutoMipmapped) { // generate mipmap levels renderer.DeviceContext.GenerateMips(_textureResView.Get(renderer)); } } }
unsafe void InitDxObjects(string name, Vector2I size, Format format, byte[] bytePattern) { Texture2DDescription desc = new Texture2DDescription(); desc.Format = format; desc.ArraySize = 1; desc.Height = size.Y; desc.Width = size.X; desc.MipLevels = MyResourceUtils.GetMipmapsCount(Math.Max(size.X, size.Y)); desc.BindFlags = BindFlags.ShaderResource; desc.CpuAccessFlags = CpuAccessFlags.None; desc.OptionFlags = ResourceOptionFlags.None; desc.Usage = ResourceUsage.Immutable; desc.SampleDescription = new SampleDescription(1, 0); Vector2I strides0; strides0.X = MyResourceUtils.GetMipmapStride(desc.Width, 0); strides0.Y = MyResourceUtils.GetMipmapStride(desc.Height, 0); byte[] dataBoxData = CreateTextureDataByPattern(strides0, bytePattern); DataBox[] dataBoxes = new DataBox[desc.MipLevels]; int blocksOffset = 0; fixed(void *ptr = dataBoxData) { for (int i = 0; i < dataBoxes.Length; i++) { dataBoxes[i].SlicePitch = 0; dataBoxes[i].RowPitch = MyResourceUtils.GetMipmapStride(size.X, i) * bytePattern.Length / 16; dataBoxes[i].DataPointer = new IntPtr(((byte *)ptr) + blocksOffset * bytePattern.Length); Vector2I blocksInMipmap; blocksInMipmap.X = MyResourceUtils.GetMipmapStride(size.X, i) / 4; blocksInMipmap.Y = MyResourceUtils.GetMipmapStride(size.Y, i) / 4; blocksOffset += blocksInMipmap.X * blocksInMipmap.Y; } m_resource = new Texture2D(MyRender11.Device, desc, dataBoxes); m_resource.DebugName = name; } m_srv = new ShaderResourceView(MyRender11.Device, m_resource); m_srv.DebugName = name; }
/// <summary> /// Upload a floatingpoint texture from the graphics hardware. /// This method is only valid for resources of type R32_Floatfloat. /// </summary> /// <param name="floatBuffer">The target float buffer to which to copy all ObjectIDs.</param> public unsafe void UploadToFloatBuffer(MemoryMappedTextureFloat floatBuffer) { // Check current format if (m_format != GraphicsHelper.DEFAULT_TEXTURE_FORMAT_OBJECT_ID) { throw new SeeingSharpGraphicsException("Invalid format for texture uploading to gdi bitmap (" + m_format + ")!"); } if (floatBuffer.Width != m_width) { throw new SeeingSharpGraphicsException("The width of the textures during texture upload does not match!"); } if (floatBuffer.Height != m_height) { throw new SeeingSharpGraphicsException("The height of the textures during texture upload does not match!"); } // Upload the texture CopyTextureToStagingResource(); // Read the data into the .Net data block SharpDX.DataBox dataBox = m_device.DeviceImmediateContextD3D11.MapSubresource( m_copyHelperTextureStaging, 0, D3D11.MapMode.Read, D3D11.MapFlags.None); try { int rowPitchSource = dataBox.RowPitch; int rowPitchDestination = floatBuffer.Width * 4; if ((rowPitchSource > 0) && (rowPitchSource < 20000) && (rowPitchDestination > 0) && (rowPitchDestination < 20000)) { for (int loopY = 0; loopY < m_height; loopY++) { CommonTools.CopyMemory( dataBox.DataPointer + loopY * rowPitchSource, floatBuffer.Pointer + loopY * rowPitchDestination, (ulong)rowPitchDestination); } } } finally { m_device.DeviceImmediateContextD3D11.UnmapSubresource(m_copyHelperTextureStaging, 0); } }
public override ImageCapture CaptureRenderTarget(RenderTarget surface) { ShaderResourceView view = new ShaderResourceView(surface.Texture.D3D11NativePointer); Texture2D source = view.Resource.QueryInterface <Texture2D>(); Texture2DDescription desc = source.Description; desc.CpuAccessFlags = CpuAccessFlags.Read; desc.Usage = ResourceUsage.Staging; desc.BindFlags = BindFlags.None; Texture2D dest = new Texture2D(_dev, desc); _dev.ImmediateContext.CopyResource(source, dest); SharpDX.DataBox data = _dev.ImmediateContext.MapSubresource(dest, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None); ImageCapture img = new ImageCapture((uint)desc.Width, (uint)desc.Height); byte[] dst = img.Pixels; IntPtr src = data.DataPointer; for (int i = 0; i < desc.Height; ++i) { int dstRow = i * (int)img.Stride; int srcRow = i * data.RowPitch; for (int j = 0; j < desc.Width; ++j) { // RGBA -> BGRA dst[dstRow + 4 * j + 2] = Noesis.Marshal.ReadByte(src, srcRow + 4 * i + 0); dst[dstRow + 4 * j + 1] = Noesis.Marshal.ReadByte(src, srcRow + 4 * i + 1); dst[dstRow + 4 * j + 0] = Noesis.Marshal.ReadByte(src, srcRow + 4 * i + 2); dst[dstRow + 4 * j + 3] = Noesis.Marshal.ReadByte(src, srcRow + 4 * i + 3); } } _dev.ImmediateContext.UnmapSubresource(dest, 0); return(img); }
// TODO GRAPHICS REFACTOR what should we do with this? /// <summary> /// Maps a subresource. /// </summary> /// <param name="resource">The resource.</param> /// <param name="subResourceIndex">Index of the sub resource.</param> /// <param name="mapMode">The map mode.</param> /// <param name="doNotWait">if set to <c>true</c> this method will return immediately if the resource is still being used by the GPU for writing. Default is false</param> /// <param name="offsetInBytes">The offset information in bytes.</param> /// <param name="lengthInBytes">The length information in bytes.</param> /// <returns>Pointer to the sub resource to map.</returns> public unsafe MappedResource MapSubresource(GraphicsResource resource, int subResourceIndex, MapMode mapMode, bool doNotWait = false, int offsetInBytes = 0, int lengthInBytes = 0) { if (resource == null) { throw new ArgumentNullException("resource"); } // This resource has just been recycled by the GraphicsResourceAllocator, we force a rename to avoid GPU=>GPU sync point if (resource.DiscardNextMap && mapMode == MapMode.WriteNoOverwrite) { mapMode = MapMode.WriteDiscard; } SharpDX.DataBox dataBox = NativeDeviceContext.MapSubresource(resource.NativeResource, subResourceIndex, (SharpDX.Direct3D11.MapMode)mapMode, doNotWait ? SharpDX.Direct3D11.MapFlags.DoNotWait : SharpDX.Direct3D11.MapFlags.None); var databox = *(DataBox *)Interop.Cast(ref dataBox); if (!dataBox.IsEmpty) { databox.DataPointer = (IntPtr)((byte *)databox.DataPointer + offsetInBytes); } return(new MappedResource(resource, subResourceIndex, databox)); }
/// <summary> /// Takes a color texture and uploads it to the given buffer. /// </summary> /// <param name="intBuffer">The target int buffer to which to copy all pixel data.</param> public unsafe void UploadToIntBuffer(MemoryMappedTexture32bpp intBuffer) { // Check current format if ((m_format != GraphicsHelper.DEFAULT_TEXTURE_FORMAT) && (m_format != GraphicsHelper.DEFAULT_TEXTURE_FORMAT_SHARING) && (m_format != GraphicsHelper.DEFAULT_TEXTURE_FORMAT_SHARING_D2D)) { throw new SeeingSharpGraphicsException(string.Format("Invalid format for texture uploading to a color map ({0})!", m_format)); } // Upload the texture CopyTextureToStagingResource(); // Read the data into the .Net data block SharpDX.DataBox dataBox = m_device.DeviceImmediateContextD3D11.MapSubresource( m_copyHelperTextureStaging, 0, D3D11.MapMode.Read, D3D11.MapFlags.None); try { int rowPitchSource = dataBox.RowPitch; int rowPitchDestination = intBuffer.Width * 4; if ((rowPitchSource > 0) && (rowPitchSource < 20000) && (rowPitchDestination > 0) && (rowPitchDestination < 20000)) { for (int loopY = 0; loopY < m_height; loopY++) { CommonTools.CopyMemory( dataBox.DataPointer + loopY * rowPitchSource, intBuffer.Pointer + loopY * rowPitchDestination, (ulong)rowPitchDestination); } } } finally { m_device.DeviceImmediateContextD3D11.UnmapSubresource(m_copyHelperTextureStaging, 0); } }
internal unsafe static SharpDX.DataBox[] ConvertDataBoxes(DataBox[] dataBoxes) { if (dataBoxes == null || dataBoxes.Length == 0) return null; var sharpDXDataBoxes = new SharpDX.DataBox[dataBoxes.Length]; fixed (void* pDataBoxes = sharpDXDataBoxes) Utilities.Write((IntPtr)pDataBoxes, dataBoxes, 0, dataBoxes.Length); return sharpDXDataBoxes; }
void CreateTexture(MyGeneratedTexture tex, string name, Texture2DDescription desc, DataBox[] dataBoxes, Vector2I size, int bytes, bool enableDxInitialisation = true) { tex.Init(name, desc, dataBoxes, size, bytes, enableDxInitialisation); }
public unsafe override void UpdateBuffer(DeviceBuffer buffer, uint bufferOffsetInBytes, IntPtr source, uint sizeInBytes) { D3D11Buffer d3dBuffer = Util.AssertSubtype <DeviceBuffer, D3D11Buffer>(buffer); if (sizeInBytes == 0) { return; } bool isDynamic = (buffer.Usage & BufferUsage.Dynamic) == BufferUsage.Dynamic; bool isStaging = (buffer.Usage & BufferUsage.Staging) == BufferUsage.Staging; bool useMap = isDynamic || isStaging; if (!useMap) { ResourceRegion?subregion = null; if ((d3dBuffer.Buffer.Description.BindFlags & BindFlags.ConstantBuffer) != BindFlags.ConstantBuffer) { // For a shader-constant buffer; set pDstBox to null. It is not possible to use // this method to partially update a shader-constant buffer subregion = new ResourceRegion() { Left = (int)bufferOffsetInBytes, Right = (int)(sizeInBytes + bufferOffsetInBytes), Bottom = 1, Back = 1 }; } if (bufferOffsetInBytes == 0) { _context.UpdateSubresource(d3dBuffer.Buffer, 0, subregion, source, 0, 0); } else { _context1.UpdateSubresource1(d3dBuffer.Buffer, 0, subregion, source, 0, 0, 0); } } else { bool updateFullBuffer = bufferOffsetInBytes == 0 && sizeInBytes == buffer.SizeInBytes; if (updateFullBuffer && isDynamic) { SharpDX.DataBox db = _context.MapSubresource( d3dBuffer.Buffer, 0, SharpDX.Direct3D11.MapMode.WriteDiscard, MapFlags.None); if (sizeInBytes < 1024) { Unsafe.CopyBlock(db.DataPointer.ToPointer(), source.ToPointer(), sizeInBytes); } else { System.Buffer.MemoryCopy(source.ToPointer(), db.DataPointer.ToPointer(), buffer.SizeInBytes, sizeInBytes); } _context.UnmapSubresource(d3dBuffer.Buffer, 0); } else { D3D11Buffer staging = GetFreeStagingBuffer(sizeInBytes); _gd.UpdateBuffer(staging, 0, source, sizeInBytes); CopyBuffer(staging, 0, buffer, bufferOffsetInBytes, sizeInBytes); _submittedStagingBuffers.Add(staging); } } }
/// <summary> /// Creates device-based resources to store a constant buffer, cube /// geometry, and vertex and pixel shaders. In some cases this will also /// store a geometry shader. /// </summary> public async void CreateDeviceDependentResourcesAsync() { ReleaseDeviceDependentResources(); usingVprtShaders = deviceResources.D3DDeviceSupportsVprt; var folder = Windows.ApplicationModel.Package.Current.InstalledLocation; // On devices that do support the D3D11_FEATURE_D3D11_OPTIONS3:: // VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature // we can avoid using a pass-through geometry shader to set the render // target array index, thus avoiding any overhead that would be // incurred by setting the geometry shader stage. var vertexShaderFileName = usingVprtShaders ? "Content\\Shaders\\VPRTVertexShader.cso" : "Content\\Shaders\\VertexShader.cso"; // Load the compiled vertex shader. var vertexShaderByteCode = await DirectXHelper.ReadDataAsync(await folder.GetFileAsync(vertexShaderFileName)); // After the vertex shader file is loaded, create the shader and input layout. vertexShader = this.ToDispose(new SharpDX.Direct3D11.VertexShader( deviceResources.D3DDevice, vertexShaderByteCode)); //TODO: Change VertexDesc to use new structure: VertexPositionTextureCoordinates SharpDX.Direct3D11.InputElement[] vertexDesc = { new SharpDX.Direct3D11.InputElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32_Float, 0, 0, SharpDX.Direct3D11.InputClassification.PerVertexData, 0), new SharpDX.Direct3D11.InputElement("TEXCOORD", 0, SharpDX.DXGI.Format.R32G32B32_Float, 12, 0, SharpDX.Direct3D11.InputClassification.PerVertexData, 0), }; inputLayout = this.ToDispose(new SharpDX.Direct3D11.InputLayout( deviceResources.D3DDevice, vertexShaderByteCode, vertexDesc)); if (!usingVprtShaders) { // Load the compiled pass-through geometry shader. var geometryShaderByteCode = await DirectXHelper.ReadDataAsync(await folder.GetFileAsync("Content\\Shaders\\GeometryShader.cso")); // After the pass-through geometry shader file is loaded, create the shader. geometryShader = this.ToDispose(new SharpDX.Direct3D11.GeometryShader( deviceResources.D3DDevice, geometryShaderByteCode)); } // Load the compiled pixel shader. var pixelShaderByteCode = await DirectXHelper.ReadDataAsync(await folder.GetFileAsync("Content\\Shaders\\PixelShader.cso")); // After the pixel shader file is loaded, create the shader. pixelShader = this.ToDispose(new SharpDX.Direct3D11.PixelShader( deviceResources.D3DDevice, pixelShaderByteCode)); //TODO: Use a photo editing app to create a texture, like GIMP2 with DDS Plugin, make sure photo width & height divisible by 4, for a cube must be an exact square //used Gimp 2 with DDS Plugin to create a 2000x2000 image and export at .dds file. //in the export options I used BC3_UNorm format, along with automatic MIP levels string textureName2 = "Content\\Textures\\nuwaupian_holding_fire3.dds"; //TODO: Create the SamplerState var samplerStateDescription = new SharpDX.Direct3D11.SamplerStateDescription(); samplerStateDescription.Filter = SharpDX.Direct3D11.Filter.MinMagMipLinear; samplerStateDescription.AddressU = SharpDX.Direct3D11.TextureAddressMode.Wrap; samplerStateDescription.AddressV = SharpDX.Direct3D11.TextureAddressMode.Wrap; samplerStateDescription.AddressW = SharpDX.Direct3D11.TextureAddressMode.Wrap; samplerStateDescription.BorderColor = new SharpDX.Mathematics.Interop.RawColor4(0f, 0f, 0f, 1f); samplerState = new SharpDX.Direct3D11.SamplerState(deviceResources.D3DDevice, samplerStateDescription); //TODO: Use the TextureLoader class to create a bitmap source from a .DDS texture file //Retreived TextureLoader from DirectXTK or DirectText Tool var bitmapSource2 = TextureLoader.LoadBitmap(new SharpDX.WIC.ImagingFactory2(), textureName2); //TODO: Create a Texture Description to describe the texture you'll be using or converting to var textDesc = new SharpDX.Direct3D11.Texture2DDescription() { Width = bitmapSource2.Size.Width, Height = bitmapSource2.Size.Height, ArraySize = 6, BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource, Usage = SharpDX.Direct3D11.ResourceUsage.Default, CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None, Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm, MipLevels = 1, OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.TextureCube, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), }; //TODO: Create Shader Resource View var shaderResourceDesc = new SharpDX.Direct3D11.ShaderResourceViewDescription() { Format = textDesc.Format, Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.TextureCube, TextureCube = new SharpDX.Direct3D11.ShaderResourceViewDescription.TextureCubeResource() { MipLevels = textDesc.MipLevels, MostDetailedMip = 0 } }; //TODO: Create 6 pointers for the 6 sides of the cube, each pointing to an 2000x2000 image you want to display IntPtr[] ptrImages = new IntPtr[6]; //TODO: Get the Stride of each image - stride is the size of 1 row pixels int stride = bitmapSource2.Size.Width * 4; //TODO: for each of the 6 pointers, create a buffer to hold the pixels using the DataStream object, using (var buffer = new SharpDX.DataStream(bitmapSource2.Size.Height * stride, true, true)) { //TODO: for each of the 6 data streams, copy the pixels into a buffer // Copy the content of the WIC to the buffer bitmapSource2.CopyPixels(stride, buffer); //TODO: for each of the 6 pointers get the IntPtr to the buffers, taking care not get rid of the buffers, pointers, or datastreams before we can create the texture cube ptrImages[0] = buffer.DataPointer; using (var buffer1 = new SharpDX.DataStream(bitmapSource2.Size.Height * stride, true, true)) { // Copy the content of the WIC to the buffer bitmapSource2.CopyPixels(stride, buffer1); ptrImages[1] = buffer1.DataPointer; using (var buffer2 = new SharpDX.DataStream(bitmapSource2.Size.Height * stride, true, true)) { // Copy the content of the WIC to the buffer bitmapSource2.CopyPixels(stride, buffer2); ptrImages[2] = buffer2.DataPointer; using (var buffer3 = new SharpDX.DataStream(bitmapSource2.Size.Height * stride, true, true)) { // Copy the content of the WIC to the buffer bitmapSource2.CopyPixels(stride, buffer3); ptrImages[3] = buffer3.DataPointer; using (var buffer4 = new SharpDX.DataStream(bitmapSource2.Size.Height * stride, true, true)) { // Copy the content of the WIC to the buffer bitmapSource2.CopyPixels(stride, buffer4); ptrImages[4] = buffer4.DataPointer; using (var buffer5 = new SharpDX.DataStream(bitmapSource2.Size.Height * stride, true, true)) { // Copy the content of the WIC to the buffer bitmapSource2.CopyPixels(stride, buffer5); ptrImages[5] = buffer5.DataPointer; //TODO: create a DataBox of the 6 pixel buffers. The DataBox is the typed array which we described in the TextureDescription and ShaderResource Description to hold the 6 sides var dataRects = new SharpDX.DataBox[] { new SharpDX.DataBox(ptrImages[0], stride, 0), new SharpDX.DataBox(ptrImages[1], stride, 0), new SharpDX.DataBox(ptrImages[2], stride, 0), new SharpDX.DataBox(ptrImages[3], stride, 0), new SharpDX.DataBox(ptrImages[4], stride, 0), new SharpDX.DataBox(ptrImages[5], stride, 0) }; //TODO: Now create the TextureCube var texture2D = new SharpDX.Direct3D11.Texture2D(deviceResources.D3DDevice, textDesc, dataRects); //TODO: Now create the TextureShaderResourceView - which will be used in the PixelShader, after this point we can release all the buffers textureResource = new SharpDX.Direct3D11.ShaderResourceView(deviceResources.D3DDevice, texture2D, shaderResourceDesc); } } } } } } //TODO: Change to VertexPositionCoordinate // Load mesh vertices. Each vertex has a position and a color. // Note that the cube size has changed from the default DirectX app // template. Windows Holographic is scaled in meters, so to draw the // cube at a comfortable size we made the cube width 0.2 m (20 cm). VertexPositionCoordinate[] cubeVertices = { new VertexPositionCoordinate(new Vector3(-0.1f, -0.1f, -0.1f), new Vector3(0.0f, 0.0f, 0.0f)), new VertexPositionCoordinate(new Vector3(-0.1f, -0.1f, 0.1f), new Vector3(0.0f, 0.0f, 1.0f)), new VertexPositionCoordinate(new Vector3(-0.1f, 0.1f, -0.1f), new Vector3(0.0f, 1.0f, 0.0f)), new VertexPositionCoordinate(new Vector3(-0.1f, 0.1f, 0.1f), new Vector3(0.0f, 1.0f, 1.0f)), new VertexPositionCoordinate(new Vector3(0.1f, -0.1f, -0.1f), new Vector3(1.0f, 0.0f, 0.0f)), new VertexPositionCoordinate(new Vector3(0.1f, -0.1f, 0.1f), new Vector3(1.0f, 0.0f, 1.0f)), new VertexPositionCoordinate(new Vector3(0.1f, 0.1f, -0.1f), new Vector3(1.0f, 1.0f, 0.0f)), new VertexPositionCoordinate(new Vector3(0.1f, 0.1f, 0.1f), new Vector3(1.0f, 1.0f, 1.0f)), }; vertexBuffer = this.ToDispose(SharpDX.Direct3D11.Buffer.Create( deviceResources.D3DDevice, SharpDX.Direct3D11.BindFlags.VertexBuffer, cubeVertices)); // Load mesh indices. Each trio of indices represents // a triangle to be rendered on the screen. // For example: 0,2,1 means that the vertices with indexes // 0, 2 and 1 from the vertex buffer compose the // first triangle of this mesh. ushort[] cubeIndices = { 2, 1, 0, // -x 2, 3, 1, 6, 4, 5, // +x 6, 5, 7, 0, 1, 5, // -y 0, 5, 4, 2, 6, 7, // +y 2, 7, 3, 0, 4, 6, // -z 0, 6, 2, 1, 3, 7, // +z 1, 7, 5, }; indexCount = cubeIndices.Length; indexBuffer = this.ToDispose(SharpDX.Direct3D11.Buffer.Create( deviceResources.D3DDevice, SharpDX.Direct3D11.BindFlags.IndexBuffer, cubeIndices)); // Create a constant buffer to store the model matrix. modelConstantBuffer = this.ToDispose(SharpDX.Direct3D11.Buffer.Create( deviceResources.D3DDevice, SharpDX.Direct3D11.BindFlags.ConstantBuffer, ref modelConstantBufferData)); // Once the cube is loaded, the object is ready to be rendered. loadingComplete = true; }
public unsafe void Load() { if (TextureState == FileTextureState.Loaded) return; Debug.Assert(m_resource == null); Debug.Assert(m_srv == null, "Texture " + Name + " in invalid state"); Image img = null; if (MyFileSystem.FileExists(m_path)) { try { using (var s = MyFileSystem.OpenRead(m_path)) { img = Image.Load(s); ImageFormatInFile = img.Description.Format; } } catch (Exception e) { MyRender11.Log.WriteLine("Error while loading texture: " + m_path + ", exception: " + e); } } bool loaded = false; if (img != null) { int skipMipmaps = 0; if (m_type != MyFileTextureEnum.GUI && m_type != MyFileTextureEnum.GPUPARTICLES && img.Description.MipLevels > 1) skipMipmaps = MyRender11.RenderSettings.TextureQuality.MipmapsToSkip(img.Description.Width, img.Description.Height); if (m_skipQualityReduction) skipMipmaps = 0; int totalSize = 0; int targetMipmaps = img.Description.MipLevels - skipMipmaps; var mipmapsData = new DataBox[(img.Description.MipLevels - skipMipmaps) * img.Description.ArraySize]; int lastSize = 0; for (int z = 0; z < img.Description.ArraySize; z++) { for (int i = 0; i < targetMipmaps; i++) { var pixels = img.GetPixelBuffer(z, i + skipMipmaps); mipmapsData[Resource.CalculateSubResourceIndex(i, z, targetMipmaps)] = new DataBox { DataPointer = pixels.DataPointer, RowPitch = pixels.RowStride }; void* data = pixels.DataPointer.ToPointer(); lastSize = pixels.BufferStride; totalSize += lastSize; } } var targetWidth = img.Description.Width >> skipMipmaps; var targetHeight = img.Description.Height >> skipMipmaps; bool overwriteFormatToSrgb = false; if (MyCompilationSymbols.ReinterpretFormatsStoredInFiles) overwriteFormatToSrgb = (m_type != MyFileTextureEnum.NORMALMAP_GLOSS) && !FormatHelper.IsSRgb(img.Description.Format); m_format = overwriteFormatToSrgb ? MyResourceUtils.MakeSrgb(img.Description.Format) : img.Description.Format; var desc = new Texture2DDescription { MipLevels = targetMipmaps, Format = m_format, Height = targetHeight, Width = targetWidth, ArraySize = img.Description.ArraySize, BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, Usage = ResourceUsage.Immutable, SampleDescription = new SampleDescription { Count = 1, Quality = 0 }, OptionFlags = img.Description.Dimension == TextureDimension.TextureCube ? ResourceOptionFlags.TextureCube : ResourceOptionFlags.None }; try { m_resource = new Texture2D(MyRender11.Device, desc, mipmapsData); m_size = new Vector2I(targetWidth, targetHeight); //m_skippedMipmaps = skipMipmaps; m_byteSize = totalSize; m_ownsData = true; m_srv = new ShaderResourceView(MyRender11.Device, m_resource); m_resource.DebugName = m_name; m_srv.DebugName = m_name; img.Dispose(); loaded = true; } catch (SharpDXException) { img.Dispose(); } } if (!loaded) { ISrvBindable replacingTexture = MyGeneratedTextureManager.ZeroTex; switch (m_type) { case MyFileTextureEnum.NORMALMAP_GLOSS: replacingTexture = MyGeneratedTextureManager.MissingNormalGlossTex; break; case MyFileTextureEnum.EXTENSIONS: replacingTexture = MyGeneratedTextureManager.MissingExtensionTex; break; case MyFileTextureEnum.ALPHAMASK: replacingTexture = MyGeneratedTextureManager.MissingAlphamaskTex; break; case MyFileTextureEnum.CUBEMAP: replacingTexture = MyGeneratedTextureManager.MissingCubeTex; break; } MyRender11.Log.WriteLine("Could not load texture: " + m_path); m_srv = replacingTexture.Srv; m_resource = replacingTexture.Resource; m_size = replacingTexture.Size; m_ownsData = false; m_byteSize = 0; MyRender11.Log.WriteLine("Missing or invalid texture: " + Name); } TextureState = FileTextureState.Loaded; }
protected override void OnRenderRegion(Rectangle[] rois, RenderArgs dstArgs, RenderArgs srcArgs) { Surface dst; Surface src; Rectangle previousTileRect = new Rectangle(); Rectangle previousResultRect = new Rectangle(); SharpDX.Direct3D11.Texture2D textureTile = null; SharpDX.Direct3D11.Buffer resultBuffer = null; SharpDX.Direct3D11.Buffer copyBuf = null; ShaderResourceView textureTileView = null; UnorderedAccessView resultView = null; SharpDX.Direct3D11.Buffer constBuffer = null; bool isComplete = false; dst = dstArgs.Surface; src = srcArgs.Surface; constBuffer = CreateConstantBuffer(base.Device, Marshal.SizeOf(this.Consts)); foreach (Rectangle rect in rois) { if (!this.IsInitialized) // || base.IsCancelRequested) return; // Add apron Rectangle tileRect = AddApron(rect, this.ApronSize, srcArgs.Bounds); // Compute Shader Parameters this.Consts = SetRenderOptions(tileRect, rect, this.Consts); // Tile texture and view if (previousTileRect.Width != tileRect.Width || previousTileRect.Height != tileRect.Height) { textureTileView.DisposeIfNotNull(); textureTile.DisposeIfNotNull(); textureTileView = CreateRegionView(out textureTile, base.Device, tileRect.Width, tileRect.Height); } // Result buffer and view if (previousResultRect.Width != rect.Width || previousResultRect.Height != rect.Height) { resultView.DisposeIfNotNull(); resultBuffer.DisposeIfNotNull(); copyBuf.DisposeIfNotNull(); resultBuffer = CreateBuffer(base.Device, rect.Width * rect.Height * BUFF_SIZE, BUFF_SIZE); resultView = CreateUnorderedAccessView(base.Device, resultBuffer); copyBuf = CreateStagingBuffer(base.Device, base.Context, resultBuffer); } // Copy tile from src to texture SharpDX.DataBox dbox = base.Context.MapSubresource(textureTile, 0, MapMode.WriteDiscard, MapFlags.None); IntPtr textureBuffer = dbox.DataPointer; IntPtr srcPointer = src.GetPointPointer(tileRect.Left, tileRect.Top); int length = tileRect.Width * BUFF_SIZE; int sourceStride = src.Stride; int dstStride = dbox.RowPitch; int tileBottom = tileRect.Bottom; for (int y = tileRect.Top; y < tileBottom; y++) { CopyMemory(textureBuffer, srcPointer, length); textureBuffer = IntPtr.Add(textureBuffer, dstStride); srcPointer = IntPtr.Add(srcPointer, sourceStride); } base.Context.UnmapSubresource(textureTile, 0); // Update constants resource unsafe { byte[] constsBytes = RawSerialize(this.Consts); fixed (byte* p = constsBytes) { var box = new SharpDX.DataBox((IntPtr)p); base.Context.UpdateSubresource(box, constBuffer); } } resourceViews[0] = textureTileView; RunComputeShader(base.Context, shader, resourceViews, new UnorderedAccessView[] { resultView }, constBuffer, (int)Math.Ceiling(rect.Width / (float)DimensionX), (int)Math.Ceiling(rect.Height / (float)DimensionY)); base.Context.CopyResource(resultBuffer, copyBuf); // Copy to destination pixels SharpDX.DataBox mappedResource = base.Context.MapSubresource(copyBuf, 0, MapMode.Read, MapFlags.None); CopyStreamToSurface(mappedResource, dst, rect); base.Context.UnmapSubresource(copyBuf, 0); previousTileRect = tileRect; previousResultRect = rect; if (this.tmr != null && rect.Top + rect.Height == src.Height && rect.Right == src.Width) { isComplete = true; } } if (isComplete) { this.tmr.Stop(); System.Windows.Forms.MessageBox.Show(this.tmr.ElapsedMilliseconds.ToString() + "ms"); } textureTileView.DisposeIfNotNull(); textureTile.DisposeIfNotNull(); resultView.DisposeIfNotNull(); resultBuffer.DisposeIfNotNull(); copyBuf.DisposeIfNotNull(); constBuffer.DisposeIfNotNull(); }
protected void SetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options) where T : struct { if (data == null) { throw new ArgumentNullException("data is null"); } if (data.Length < (startIndex + elementCount)) { throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); } var bufferSize = VertexCount * VertexDeclaration.VertexStride; if ((vertexStride > bufferSize) || (vertexStride < VertexDeclaration.VertexStride)) { throw new ArgumentOutOfRangeException("One of the following conditions is true:\nThe vertex stride is larger than the vertex buffer.\nThe vertex stride is too small for the type of data requested."); } #if !PSS var elementSizeInBytes = Marshal.SizeOf(typeof(T)); #endif #if DIRECTX if (_isDynamic) { // We assume discard by default. var mode = SharpDX.Direct3D11.MapMode.WriteDiscard; if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite) { mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite; } SharpDX.DataStream stream; lock (graphicsDevice._d3dContext) { graphicsDevice._d3dContext.MapSubresource( _buffer, mode, SharpDX.Direct3D11.MapFlags.None, out stream); stream.Position = offsetInBytes; stream.WriteRange(data, startIndex, elementCount); graphicsDevice._d3dContext.UnmapSubresource(_buffer, 0); } } else { var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); var startBytes = startIndex * elementSizeInBytes; var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes); var box = new SharpDX.DataBox(dataPtr, 1, 0); var region = new SharpDX.Direct3D11.ResourceRegion(); region.Top = 0; region.Front = 0; region.Back = 1; region.Bottom = 1; region.Left = offsetInBytes; region.Right = offsetInBytes + (elementCount * elementSizeInBytes); lock (graphicsDevice._d3dContext) graphicsDevice._d3dContext.UpdateSubresource(box, _buffer, 0, region); dataHandle.Free(); } #elif PSS if (_vertexArray == null) { _vertexArray = new T[VertexCount]; } Array.Copy(data, offsetInBytes / vertexStride, _vertexArray, startIndex, elementCount); #else Threading.BlockOnUIThread(() => { var sizeInBytes = elementSizeInBytes * elementCount; GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); GraphicsExtensions.CheckGLError(); if (options == SetDataOptions.Discard) { // By assigning NULL data to the buffer this gives a hint // to the device to discard the previous content. GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)bufferSize, IntPtr.Zero, _isDynamic ? BufferUsageHint.StreamDraw : BufferUsageHint.StaticDraw); GraphicsExtensions.CheckGLError(); } GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)offsetInBytes, (IntPtr)sizeInBytes, data); GraphicsExtensions.CheckGLError(); }); #endif }
unsafe void InitDxObjects(string name, Vector2I size, Format format, byte[] bytePattern) { Texture2DDescription desc = new Texture2DDescription(); desc.Format = format; desc.ArraySize = 1; desc.Height = size.Y; desc.Width = size.X; desc.MipLevels = MyResourceUtils.GetMipmapsCount(Math.Max(size.X, size.Y)); desc.BindFlags = BindFlags.ShaderResource; desc.CpuAccessFlags = CpuAccessFlags.None; desc.OptionFlags = ResourceOptionFlags.None; desc.Usage = ResourceUsage.Immutable; desc.SampleDescription = new SampleDescription(1, 0); Vector2I strides0; strides0.X = MyResourceUtils.GetMipmapStride(desc.Width, 0); strides0.Y = MyResourceUtils.GetMipmapStride(desc.Height, 0); byte[] dataBoxData = CreateTextureDataByPattern(strides0, bytePattern); DataBox[] dataBoxes = new DataBox[desc.MipLevels]; int blocksOffset = 0; fixed (void* ptr = dataBoxData) { for (int i = 0; i < dataBoxes.Length; i++) { dataBoxes[i].SlicePitch = 0; dataBoxes[i].RowPitch = MyResourceUtils.GetMipmapStride(size.X, i) * bytePattern.Length / 16; dataBoxes[i].DataPointer = new IntPtr(((byte*)ptr) + blocksOffset * bytePattern.Length); Vector2I blocksInMipmap; blocksInMipmap.X = MyResourceUtils.GetMipmapStride(size.X, i) / 4; blocksInMipmap.Y = MyResourceUtils.GetMipmapStride(size.Y, i) / 4; blocksOffset += blocksInMipmap.X * blocksInMipmap.Y; } m_resource = new Texture2D(MyRender11.Device, desc, dataBoxes); m_resource.DebugName = name; } m_srv = new ShaderResourceView(MyRender11.Device, m_resource); m_srv.DebugName = name; }
private void PlatformSetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options, int bufferSize, int elementSizeInBytes) where T : struct { GenerateIfRequired(); if (_isDynamic) { // We assume discard by default. var mode = SharpDX.Direct3D11.MapMode.WriteDiscard; if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite) { mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite; } var d3dContext = GraphicsDevice._d3dContext; lock (d3dContext) { var dataBox = d3dContext.MapSubresource(_buffer, 0, mode, SharpDX.Direct3D11.MapFlags.None); if (vertexStride == elementSizeInBytes) { SharpDX.Utilities.Write(dataBox.DataPointer + offsetInBytes, data, startIndex, elementCount); } else { for (int i = 0; i < elementCount; i++) { SharpDX.Utilities.Write(dataBox.DataPointer + offsetInBytes + i * vertexStride, data, startIndex + i, 1); } } d3dContext.UnmapSubresource(_buffer, 0); } } else { var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); try { var startBytes = startIndex * elementSizeInBytes; var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes); var d3dContext = GraphicsDevice._d3dContext; if (vertexStride == elementSizeInBytes) { var box = new SharpDX.DataBox(dataPtr, elementCount * elementSizeInBytes, 0); var region = new SharpDX.Direct3D11.ResourceRegion(); region.Top = 0; region.Front = 0; region.Back = 1; region.Bottom = 1; region.Left = offsetInBytes; region.Right = offsetInBytes + (elementCount * elementSizeInBytes); lock (d3dContext) d3dContext.UpdateSubresource(box, _buffer, 0, region); } else { // Copy the buffer to a staging resource, so that any elements we don't write to will still be correct. var stagingDesc = _buffer.Description; stagingDesc.BindFlags = SharpDX.Direct3D11.BindFlags.None; stagingDesc.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.Read | SharpDX.Direct3D11.CpuAccessFlags.Write; stagingDesc.Usage = SharpDX.Direct3D11.ResourceUsage.Staging; stagingDesc.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None; using (var stagingBuffer = new SharpDX.Direct3D11.Buffer(GraphicsDevice._d3dDevice, stagingDesc)) { lock (d3dContext) { d3dContext.CopyResource(_buffer, stagingBuffer); // Map the staging resource to a CPU accessible memory var box = d3dContext.MapSubresource(stagingBuffer, 0, SharpDX.Direct3D11.MapMode.Read, SharpDX.Direct3D11.MapFlags.None); for (int i = 0; i < elementCount; i++) { SharpDX.Utilities.CopyMemory( box.DataPointer + i * vertexStride + offsetInBytes, dataPtr + i * elementSizeInBytes, elementSizeInBytes); } // Make sure that we unmap the resource in case of an exception d3dContext.UnmapSubresource(stagingBuffer, 0); // Copy back from staging resource to real buffer. d3dContext.CopyResource(stagingBuffer, _buffer); } } } } finally { dataHandle.Free(); } } }
public void SetData<T>(int level, Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct { if (data == null) throw new ArgumentNullException("data"); #if OPENGL Threading.BlockOnUIThread(() => { #endif #if !PSM var elementSizeInByte = Marshal.SizeOf(typeof(T)); var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); var startBytes = startIndex * elementSizeInByte; var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes); #endif int x, y, w, h; if (rect.HasValue) { x = rect.Value.X; y = rect.Value.Y; w = rect.Value.Width; h = rect.Value.Height; } else { x = 0; y = 0; w = Math.Max(width >> level, 1); h = Math.Max(height >> level, 1); } #if DIRECTX var box = new SharpDX.DataBox(dataPtr, GetPitch(w), 0); var region = new SharpDX.Direct3D11.ResourceRegion(); region.Top = y; region.Front = 0; region.Back = 1; region.Bottom = y + h; region.Left = x; region.Right = x + w; // TODO: We need to deal with threaded contexts here! var d3dContext = GraphicsDevice._d3dContext; lock (d3dContext) d3dContext.UpdateSubresource(box, _texture, level, region); #elif PSM _texture2D.SetPixels(level, data, _texture2D.Format, startIndex, 0, x, y, w, h); #elif OPENGL // Store the current bound texture. var prevTexture = GraphicsExtensions.GetBoundTexture2D(); GenerateGLTextureIfRequired(); GL.BindTexture(TextureTarget.Texture2D, this.glTexture); GraphicsExtensions.CheckGLError(); if (glFormat == (GLPixelFormat)All.CompressedTextureFormats) { if (rect.HasValue) { GL.CompressedTexSubImage2D(TextureTarget.Texture2D, level, x, y, w, h, #if GLES glInternalFormat, #else glFormat, #endif data.Length - startBytes, dataPtr); GraphicsExtensions.CheckGLError(); } else { GL.CompressedTexImage2D(TextureTarget.Texture2D, level, glInternalFormat, w, h, 0, data.Length - startBytes, dataPtr); GraphicsExtensions.CheckGLError(); } } else { // Set pixel alignment to match texel size in bytes GL.PixelStore(PixelStoreParameter.UnpackAlignment, GraphicsExtensions.Size(this.Format)); if (rect.HasValue) { GL.TexSubImage2D(TextureTarget.Texture2D, level, x, y, w, h, glFormat, glType, dataPtr); GraphicsExtensions.CheckGLError(); } else { GL.TexImage2D(TextureTarget.Texture2D, level, #if GLES (int)glInternalFormat, #else glInternalFormat, #endif w, h, 0, glFormat, glType, dataPtr); GraphicsExtensions.CheckGLError(); } // Return to default pixel alignment GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4); } #if !ANDROID GL.Finish(); GraphicsExtensions.CheckGLError(); #endif // Restore the bound texture. GL.BindTexture(TextureTarget.Texture2D, prevTexture); GraphicsExtensions.CheckGLError(); #endif // OPENGL #if !PSM dataHandle.Free(); #endif #if OPENGL #if !ANDROID // Required to make sure that any texture uploads on a thread are completed // before the main thread tries to use the texture. GL.Finish(); #endif }); #endif }
public void Render(RenderFrame frame) { if (SwapChain == null) return; ///////////////////////////////////////////////// // update ///////////////////////////////////////////////// foreach (var resource in frame.Resources) { switch (resource.RenderResourceType) { case RenderResourceType.Texture: //TextureManager.Ensure(device, resource as TextureResource); break; case RenderResourceType.Sampler: //SamplerManager.Ensure(device, resource as SamplerResource); break; case RenderResourceType.Shader: m_shaderManager.Ensure(D3DDevice, resource as ShaderResource); break; case RenderResourceType.VertexBuffer: m_vertexBufferManager.Ensure(D3DDevice, resource as VertexBufferResource); break; case RenderResourceType.BlendState: //BlendStateManager.Ensure(device, resource as BlendStateResource); break; case RenderResourceType.DepthStencilState: //DepthStencilStateManager.Ensure(device, resource as DepthStencilStateResource); break; default: throw new NotImplementedException(resource.ToString()); } } ///////////////////////////////////////////////// // render ///////////////////////////////////////////////// m_pass = new ShaderPass(); using (Backbuffer = SwapChain.GetBackBuffer<SharpDX.Direct3D11.Texture2D>(0)) using (RTV = new SharpDX.Direct3D11.RenderTargetView(D3DDevice, Backbuffer)) { var context = D3DDevice.ImmediateContext; foreach (var c in frame.Commands) { switch (c.RenderCommandType) { /* case RenderCommandType.RenderTargets_Set: { var command = c as RenderTargetsSetCommand; var depthStencil = m_resources.TextureManager.Get(command.DepthStencil); var renderTargets = m_resources.TextureManager.Get(command.RenderTargets); context.OutputMerger.SetTargets( depthStencil != null ? depthStencil.DepthStencilView : null , renderTargets.Select(r => r.RenderTargetView).ToArray()); } break; case RenderCommandType.Viewport_Set: { var command = c as ViewportSetCommand; context.Rasterizer.SetViewports(new SharpDX.ViewportF[] { command.Viewport }); } break; */ case RenderCommandType.Clear_Backbuffer: { var command = c as BackbufferClearCommand; context.ClearRenderTargetView(RTV, command.Color.ToSharpDX()); context.OutputMerger.SetTargets((SharpDX.Direct3D11.DepthStencilView)null, new SharpDX.Direct3D11.RenderTargetView[] { RTV }); context.Rasterizer.SetViewports(new [] { new SharpDX.Mathematics.Interop.RawViewportF { X=0, Y=0, Width=Backbuffer.Description.Width, Height=Backbuffer.Description.Height, } }); } break; /* case RenderCommandType.Clear_Color: { var command = c as RenderTargetClearCommand; var renderTarget = m_resources.TextureManager.Get(command.ResourceID); if (renderTarget != null) { context.ClearRenderTargetView(renderTarget.RenderTargetView, command.Color); } } break; case RenderCommandType.Clear_Depth: { var command = c as DepthStencilClearCommand; var depthStencil = m_resources.TextureManager.Get(command.ResourceID); if (depthStencil != null) { context.ClearDepthStencilView(depthStencil.DepthStencilView , SharpDX.Direct3D11.DepthStencilClearFlags.Depth , command.Depth, command.Stencil); } } break; */ case RenderCommandType.VertexBuffer_Update: { var command = c as VertexBufferUpdateCommand; var vertexBuffer = m_vertexBufferManager.Get(command.ResourceID); if (vertexBuffer != null) { if (command.Ptr != IntPtr.Zero) { var data = new SharpDX.DataBox(command.Ptr); context.UpdateSubresource(data, vertexBuffer.Vertices); } } } break; case RenderCommandType.VertexBuffer_Set: { var command = c as VertexBufferSetCommand; var vertexBuffer = m_vertexBufferManager.Get(command.ResourceID); if (vertexBuffer != null) { context.InputAssembler.PrimitiveTopology = vertexBuffer.Topology; context.InputAssembler.SetVertexBuffers(0, new SharpDX.Direct3D11.VertexBufferBinding(vertexBuffer.Vertices , vertexBuffer.Stride, 0)); if (vertexBuffer.Indices != null) { context.InputAssembler.SetIndexBuffer(vertexBuffer.Indices, SharpDX.DXGI.Format.R32_UInt, 0); } m_vertexBuffer = vertexBuffer; } } break; case RenderCommandType.ShaderVriable_Set: { var command = c as ShaderVariableSetCommand; m_pass.SetConstantVariable(command); } break; /* case RenderCommandType.ShaderTexture_Set: { var command = c as ShaderTextureSetCommand; var texture = m_resources.TextureManager.Get(command.ResourceID); if (texture != null) { m_pass.SetSRV(context, command.Key, texture.ShaderResourceView); } } break; case RenderCommandType.ShaderSampler_Set: { var command = c as ShaderSamplerSetCommand; Pass.SetSampler(command); } break; */ case RenderCommandType.Shader_Set: { var command = c as ShaderSetCommand; switch (command.ShaderStage) { case ShaderStage.Vertex: { var vertexShader = m_shaderManager.Get(command.ResourceID) as VertexShaderStage; if (vertexShader != null) { context.VertexShader.Set(vertexShader.Shader); //context.InputAssembler.InputLayout = vertexShader.VertexLayout; m_pass.VertexShader = vertexShader; } } break; case ShaderStage.Geometry: { var geometryShader = m_shaderManager.Get(command.ResourceID) as GeometryShaderStage; if (geometryShader != null) { context.GeometryShader.Set(geometryShader.Shader); m_pass.GeometryShader = geometryShader; } } break; case ShaderStage.Pixel: { var pixelShader = m_shaderManager.Get(command.ResourceID) as PixelShaderStage; if (pixelShader != null) { context.PixelShader.Set(pixelShader.Shader); m_pass.PixelShader = pixelShader; } } break; default: throw new NotImplementedException(); } } break; case RenderCommandType.Shader_DrawSubMesh: { var command = c as ShaderDrawSubMeshCommand; if (m_pass.VertexShader != null) { context.InputAssembler.InputLayout = m_pass.VertexShader.VertexLayout; // 定数バッファの適用 m_pass.Apply(context); if (m_vertexBuffer != null) { if (m_vertexBuffer.Indices != null) { context.DrawIndexed(command.Count, command.Offset, 0); } else { context.Draw(command.Count, command.Offset); } } } } break; /* case RenderCommandType.BlendState_Set: { var command = c as BlendStateSetCommand; var blendState = m_resources.BlendStateManager.Get(command.ResourceID); if (blendState == null) { return; } context.OutputMerger.SetBlendState(blendState.State, SharpDX.Color4.White); } break; case RenderCommandType.DepthStencilState_Set: { var command = c as DepthStencilStateSetCommand; var depthStencilState = m_resources.DepthStencilStateManager.Get(command.ResourceID); if (depthStencilState == null) { return; } context.OutputMerger.SetDepthStencilState(depthStencilState.State); } break; */ } } context.Flush(); } Backbuffer = null; RTV = null; ///////////////////////////////////////////////// // flip ///////////////////////////////////////////////// var flags = SharpDX.DXGI.PresentFlags.None; flags|=SharpDX.DXGI.PresentFlags.DoNotWait; SwapChain.Present(0, flags, new SharpDX.DXGI.PresentParameters()); }
public void Load() { if (TextureState == FileTextureState.Loaded) { return; } string path = Path.Combine(MyFileSystem.ContentPath, Name); Debug.Assert(m_resource == null); Debug.Assert(m_srv == null, "Texture " + Name + " in invalid state"); Image img = null; if (MyFileSystem.FileExists(path)) { try { using (var s = MyFileSystem.OpenRead(path)) { img = Image.Load(s); m_imageFormatInFile = img.Description.Format; } } catch (Exception e) { MyRender11.Log.WriteLine("Error while loading texture: " + path + ", exception: " + e); } } bool loaded = false; if (img != null) { int skipMipmaps = (m_type != MyFileTextureEnum.GUI && m_type != MyFileTextureEnum.GPUPARTICLES && img.Description.MipLevels > 1) ? MyRender11.RenderSettings.TextureQuality.MipmapsToSkip(img.Description.Width, img.Description.Height) : 0; if (m_skipQualityReduction) { skipMipmaps = 0; } int totalSize = 0; int targetMipmaps = img.Description.MipLevels - skipMipmaps; var mipmapsData = new DataBox[(img.Description.MipLevels - skipMipmaps) * img.Description.ArraySize]; long delta = 0; int lastSize = 0; for (int z = 0; z < img.Description.ArraySize; z++) { for (int i = 0; i < targetMipmaps; i++) { var pixels = img.GetPixelBuffer(z, i + skipMipmaps); mipmapsData[Resource.CalculateSubResourceIndex(i, z, targetMipmaps)] = new DataBox { DataPointer = pixels.DataPointer, RowPitch = pixels.RowStride }; delta = pixels.DataPointer.ToInt64() - img.DataPointer.ToInt64(); lastSize = pixels.BufferStride; totalSize += lastSize; } } var targetWidth = img.Description.Width >> skipMipmaps; var targetHeight = img.Description.Height >> skipMipmaps; bool overwriteFormatToSrgb = (m_type != MyFileTextureEnum.NORMALMAP_GLOSS) && !FormatHelper.IsSRgb(img.Description.Format); var desc = new Texture2DDescription { MipLevels = targetMipmaps, Format = overwriteFormatToSrgb ? MyResourceUtils.MakeSrgb(img.Description.Format) : img.Description.Format, Height = targetHeight, Width = targetWidth, ArraySize = img.Description.ArraySize, BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, Usage = ResourceUsage.Immutable, SampleDescription = new SampleDescription { Count = 1, Quality = 0 }, OptionFlags = img.Description.Dimension == TextureDimension.TextureCube ? ResourceOptionFlags.TextureCube : ResourceOptionFlags.None }; try { m_resource = new Texture2D(MyRender11.Device, desc, mipmapsData); m_size = new Vector2I(targetWidth, targetHeight); //m_skippedMipmaps = skipMipmaps; m_fileExists = true; m_byteSize = totalSize; m_ownsData = true; m_srv = new ShaderResourceView(MyRender11.Device, m_resource); m_resource.DebugName = m_name; m_srv.DebugName = m_name; img.Dispose(); loaded = true; } catch (SharpDXException) { img.Dispose(); } } if (!loaded) { ISrvBindable replacingTexture = MyGeneratedTextureManager.ZeroTex; switch (m_type) { case MyFileTextureEnum.NORMALMAP_GLOSS: replacingTexture = MyGeneratedTextureManager.MissingNormalGlossTex; break; case MyFileTextureEnum.EXTENSIONS: replacingTexture = MyGeneratedTextureManager.MissingExtensionTex; break; case MyFileTextureEnum.ALPHAMASK: replacingTexture = MyGeneratedTextureManager.MissingAlphamaskTex; break; case MyFileTextureEnum.CUBEMAP: replacingTexture = MyGeneratedTextureManager.MissingCubeTex; break; } MyRender11.Log.WriteLine("Could not load texture: " + path); m_srv = replacingTexture.Srv; m_resource = replacingTexture.Resource; m_size = replacingTexture.Size; m_ownsData = false; m_fileExists = false; m_byteSize = 0; MyRender11.Log.WriteLine("Missing or invalid texture: " + Name); } TextureState = FileTextureState.Loaded; }
public void SetData<T>(int level, Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct { if (data == null) throw new ArgumentNullException("data"); #if OPENGL Threading.BlockOnUIThread(() => { #endif #if !PSM var elementSizeInByte = Marshal.SizeOf(typeof(T)); var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); // Use try..finally to make sure dataHandle is freed in case of an error try { var startBytes = startIndex * elementSizeInByte; var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes); #endif int x, y, w, h; if (rect.HasValue) { x = rect.Value.X; y = rect.Value.Y; w = rect.Value.Width; h = rect.Value.Height; } else { x = 0; y = 0; w = Math.Max(width >> level, 1); h = Math.Max(height >> level, 1); // For DXT textures the width and height of each level is a multiple of 4. // OpenGL only: The last two mip levels require the width and height to be // passed as 2x2 and 1x1, but there needs to be enough data passed to occupy // a 4x4 block. // Ref: http://www.mentby.com/Group/mac-opengl/issue-with-dxt-mipmapped-textures.html if (_format == SurfaceFormat.Dxt1 || _format == SurfaceFormat.Dxt1a || _format == SurfaceFormat.Dxt3 || _format == SurfaceFormat.Dxt5) { #if DIRECTX w = (w + 3) & ~3; h = (h + 3) & ~3; #else if (w > 4) w = (w + 3) & ~3; if (h > 4) h = (h + 3) & ~3; #endif } } #if DIRECTX var box = new SharpDX.DataBox(dataPtr, GetPitch(w), 0); var region = new SharpDX.Direct3D11.ResourceRegion(); region.Top = y; region.Front = 0; region.Back = 1; region.Bottom = y + h; region.Left = x; region.Right = x + w; // TODO: We need to deal with threaded contexts here! var d3dContext = GraphicsDevice._d3dContext; lock (d3dContext) d3dContext.UpdateSubresource(box, GetTexture(), level, region); #elif PSM _texture2D.SetPixels(level, data, _texture2D.Format, startIndex, 0, x, y, w, h); #elif OPENGL // Store the current bound texture. var prevTexture = GraphicsExtensions.GetBoundTexture2D(); GenerateGLTextureIfRequired(); GL.BindTexture(TextureTarget.Texture2D, this.glTexture); GraphicsExtensions.CheckGLError(); if (glFormat == (GLPixelFormat)All.CompressedTextureFormats) { if (rect.HasValue) { GL.CompressedTexSubImage2D(TextureTarget.Texture2D, level, x, y, w, h, #if GLES glInternalFormat, #else glFormat, #endif data.Length - startBytes, dataPtr); GraphicsExtensions.CheckGLError(); } else { GL.CompressedTexImage2D(TextureTarget.Texture2D, level, glInternalFormat, w, h, 0, data.Length - startBytes, dataPtr); GraphicsExtensions.CheckGLError(); } } else { // Set pixel alignment to match texel size in bytes GL.PixelStore(PixelStoreParameter.UnpackAlignment, GraphicsExtensions.Size(this.Format)); if (rect.HasValue) { GL.TexSubImage2D(TextureTarget.Texture2D, level, x, y, w, h, glFormat, glType, dataPtr); GraphicsExtensions.CheckGLError(); } else { GL.TexImage2D(TextureTarget.Texture2D, level, #if GLES (int)glInternalFormat, #else glInternalFormat, #endif w, h, 0, glFormat, glType, dataPtr); GraphicsExtensions.CheckGLError(); } // Return to default pixel alignment GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4); } #if !ANDROID GL.Finish(); GraphicsExtensions.CheckGLError(); #endif // Restore the bound texture. GL.BindTexture(TextureTarget.Texture2D, prevTexture); GraphicsExtensions.CheckGLError(); #endif // OPENGL #if !PSM } finally { dataHandle.Free(); } #endif #if OPENGL #if !ANDROID // Required to make sure that any texture uploads on a thread are completed // before the main thread tries to use the texture. GL.Finish(); #endif }); #endif }
public void Apply(SharpDX.Direct3D11.DeviceContext context) { if (VertexShader != null) { if (VertexShader.ConstantBufferSlots != null) { VertexShader.ConstantBufferSlots .Where(slot => slot.BackingStore != null && slot.BackingStore.Buffer != null) .ForEach(slot => { var data = new SharpDX.DataBox(slot.BackingStore.Buffer.Ptr); context.UpdateSubresource(data, slot.Buffer); context.VertexShader.SetConstantBuffer(slot.Index, slot.Buffer); }); } } if (GeometryShader != null) { if (GeometryShader.ConstantBufferSlots != null) { GeometryShader.ConstantBufferSlots .Where(slot => slot.BackingStore != null && slot.BackingStore.Buffer != null) .ForEach(slot => { var data = new SharpDX.DataBox(slot.BackingStore.Buffer.Ptr); context.UpdateSubresource(data, slot.Buffer); context.GeometryShader.SetConstantBuffer(slot.Index, slot.Buffer); }); } } if (PixelShader != null) { if (PixelShader.ConstantBufferSlots != null) { PixelShader.ConstantBufferSlots .Where(slot => slot.BackingStore != null && slot.BackingStore.Buffer != null) .ForEach(slot => { var data = new SharpDX.DataBox(slot.BackingStore.Buffer.Ptr); context.UpdateSubresource(data, slot.Buffer); context.PixelShader.SetConstantBuffer(slot.Index, slot.Buffer); }); } } /* // set textures Textures.ForEach((t, i) => context.PixelShader.SetShaderResource(i, t.ShaderResourceView)); // sampler Samplers.ForEach((s, i) => context.PixelShader.SetSampler(i, s.State)); */ }
static unsafe void Reset(MyGeneratedTexture tex, byte[] data, int nchannels) { if (data == null) { tex.Reset(null); } else { fixed (byte* dptr = data) { int numMiplevels = tex.NumMipLevels; DataBox[] dataBox = new DataBox[numMiplevels]; int width = tex.Size.X; int height = tex.Size.Y; int offset = 0; for (int i = 0; i < numMiplevels; ++i) { dataBox[i].DataPointer = new IntPtr(dptr + offset); dataBox[i].RowPitch = width * nchannels; offset += width * height * nchannels; width >>= 1; height >>= 1; } tex.Reset(dataBox); } } }