public void Evaluate(int SpreadMax) { if (this.FTextureIn.PluginIO.IsConnected) { if (this.RenderRequest != null) { this.RenderRequest(this, this.FHost); } if (this.AssignedContext == null) { this.SetNull(); return; } this.FPointer.SliceCount = SpreadMax; DX11RenderContext context = this.AssignedContext; for (int i = 0; i < this.FTextureIn.SliceCount; i++) { try { if (this.FTextureIn[i].Contains(context)) { //Convert texture so it has no mips if (tex == null) { Texture2D t = this.FTextureIn[0][context].Resource; Texture2DDescription desc = t.Description; desc.OptionFlags = ResourceOptionFlags.Shared; desc.MipLevels = 1; this.tex = new Texture2D(context.Device, desc); var SharedResource = new SlimDX.DXGI.Resource(this.tex); this.FPointer[0] = SharedResource.SharedHandle.ToInt32(); } this.AssignedContext.CurrentDeviceContext.CopyResource(this.FTextureIn[0][context].Resource, this.tex); } else { this.SetDefault(i); } } catch { this.SetDefault(i); } } } else { this.SetNull(); } }
public void Evaluate(int SpreadMax) { if (this.FTextureIn.PluginIO.IsConnected) { if (this.RenderRequest != null) { this.RenderRequest(this, this.FHost); } if (this.AssignedContext == null) { this.SetNull(); return; } this.FPointer.SliceCount = SpreadMax; DX11RenderContext context = this.AssignedContext; try { if (this.FTextureIn[0].Contains(context)) { if (tex != null) { Texture2D t = this.FTextureIn[0][context].Resource; if (t.Description.Width != this.tex.Description.Width || t.Description.Height != this.tex.Description.Height || t.Description.Format != this.tex.Description.Format) { this.SharedResource.Dispose(); this.SharedResource = null; this.tex.Dispose(); this.tex = null; } if (t.Description.MipLevels > 1) { this.FPointer[0] = 0; throw new Exception("Sharing texture with more than one mip level is not allowed"); } if (t.Description.SampleDescription.Count > 1) { this.FPointer[0] = 0; throw new Exception("Sharing multisampled texture is not allowed"); } } //Convert texture so it has no mips if (tex == null) { Texture2D t = this.FTextureIn[0][context].Resource; Texture2DDescription desc = t.Description; desc.BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget; desc.OptionFlags = ResourceOptionFlags.Shared; desc.MipLevels = 1; this.tex = new Texture2D(context.Device, desc); this.SharedResource = new SlimDX.DXGI.Resource(this.tex); this.FPointer[0] = SharedResource.SharedHandle.ToInt64(); } this.AssignedContext.CurrentDeviceContext.CopyResource(this.FTextureIn[0][context].Resource, this.tex); } else { this.SetDefault(0); } } catch { this.SetDefault(0); } } else { this.SetNull(); } }
IntPtr GetSharedHandle(SlimDX.Direct3D11.Texture2D Texture) { SlimDX.DXGI.Resource resource = new SlimDX.DXGI.Resource(Texture); IntPtr result = resource.SharedHandle; resource.Dispose(); return result; }
private IntPtr GetSharedHandle(SlimDX.Direct3D11.Texture2D tex) { SlimDX.DXGI.Resource resource = new SlimDX.DXGI.Resource(tex); ; //Texture.QueryInterface<SlimDX.DXGI.Resource>(); IntPtr result = resource.SharedHandle; resource.Dispose(); return result; }
public TextRenderer(Device device) { using (var factory = new SlimDX.DXGI.Factory1()) { using (var adapter = factory.GetAdapter1(0)) { this.device = new SlimDX.Direct3D10_1.Device1( adapter, SlimDX.Direct3D10.DriverType.Hardware, SlimDX.Direct3D10.DeviceCreationFlags.BgraSupport, SlimDX.Direct3D10_1.FeatureLevel.Level_10_0 ); // Create the DirectX11 texture2D. This texture will be shared with the DirectX10 // device. The DirectX10 device will be used to render text onto this texture. DirectX11 // will then draw this texture (blended) onto the screen. // The KeyedMutex flag is required in order to share this resource. textureD3D11 = new SlimDX.Direct3D11.Texture2D(device.Handle, new SlimDX.Direct3D11.Texture2DDescription { Width = device.Form.Width, Height = device.Form.Height, MipLevels = 1, ArraySize = 1, Format = SlimDX.DXGI.Format.B8G8R8A8_UNorm, SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0), Usage = SlimDX.Direct3D11.ResourceUsage.Default, BindFlags = SlimDX.Direct3D11.BindFlags.RenderTarget | SlimDX.Direct3D11.BindFlags.ShaderResource, CpuAccessFlags = SlimDX.Direct3D11.CpuAccessFlags.None, OptionFlags = SlimDX.Direct3D11.ResourceOptionFlags.KeyedMutex }); // A DirectX10 Texture2D sharing the DirectX11 Texture2D var sharedResource = new SlimDX.DXGI.Resource(textureD3D11); var textureD3D10 = this.device.OpenSharedResource<SlimDX.Direct3D10.Texture2D>(sharedResource.SharedHandle); // The KeyedMutex is used just prior to writing to textureD3D11 or textureD3D10. // This is how DirectX knows which DirectX (10 or 11) is supposed to be writing // to the shared texture. The keyedMutex is just defined here, they will be used // a bit later. mutex10 = new SlimDX.DXGI.KeyedMutex(textureD3D10); mutex11 = new SlimDX.DXGI.KeyedMutex(textureD3D11); // Direct2D Factory SlimDX.Direct2D.Factory d2Factory = new SlimDX.Direct2D.Factory( SlimDX.Direct2D.FactoryType.SingleThreaded, SlimDX.Direct2D.DebugLevel.Information ); // Direct Write factory SlimDX.DirectWrite.Factory dwFactory = new SlimDX.DirectWrite.Factory( SlimDX.DirectWrite.FactoryType.Isolated ); // The textFormat we will use to draw text with textFormat = new SlimDX.DirectWrite.TextFormat( dwFactory, "Arial", SlimDX.DirectWrite.FontWeight.Normal, SlimDX.DirectWrite.FontStyle.Normal, SlimDX.DirectWrite.FontStretch.Normal, 24, "en-US" ); textFormat.TextAlignment = SlimDX.DirectWrite.TextAlignment.Center; textFormat.ParagraphAlignment = SlimDX.DirectWrite.ParagraphAlignment.Center; // Query for a IDXGISurface. // DirectWrite and DirectX10 can interoperate thru DXGI. var surface = textureD3D10.AsSurface(); var rtp = new SlimDX.Direct2D.RenderTargetProperties(); rtp.MinimumFeatureLevel = SlimDX.Direct2D.FeatureLevel.Direct3D10; rtp.Type = SlimDX.Direct2D.RenderTargetType.Hardware; rtp.Usage = SlimDX.Direct2D.RenderTargetUsage.None; rtp.PixelFormat = new SlimDX.Direct2D.PixelFormat(SlimDX.DXGI.Format.Unknown, SlimDX.Direct2D.AlphaMode.Premultiplied); dwRenderTarget = SlimDX.Direct2D.RenderTarget.FromDXGI(d2Factory, surface, rtp); // Brush used to DrawText brushSolidWhite = new SlimDX.Direct2D.SolidColorBrush( dwRenderTarget, new SlimDX.Color4(1, 1, 1, 1) ); // Think of the shared textureD3D10 as an overlay. // The overlay needs to show the text but let the underlying triangle (or whatever) // show thru, which is accomplished by blending. var bsd = new SlimDX.Direct3D11.BlendStateDescription(); bsd.RenderTargets[0].BlendEnable = true; bsd.RenderTargets[0].SourceBlend = SlimDX.Direct3D11.BlendOption.SourceAlpha; bsd.RenderTargets[0].DestinationBlend = SlimDX.Direct3D11.BlendOption.InverseSourceAlpha; bsd.RenderTargets[0].BlendOperation = SlimDX.Direct3D11.BlendOperation.Add; bsd.RenderTargets[0].SourceBlendAlpha = SlimDX.Direct3D11.BlendOption.One; bsd.RenderTargets[0].DestinationBlendAlpha = SlimDX.Direct3D11.BlendOption.Zero; bsd.RenderTargets[0].BlendOperationAlpha = SlimDX.Direct3D11.BlendOperation.Add; bsd.RenderTargets[0].RenderTargetWriteMask = SlimDX.Direct3D11.ColorWriteMaskFlags.All; BlendState_Transparent = SlimDX.Direct3D11.BlendState.FromDescription(device.Handle, bsd); // Load Effect. This includes both the vertex and pixel shaders. // Also can include more than one technique. var shaderByteCode = SlimDX.D3DCompiler.ShaderBytecode.CompileFromFile( "texteffect.fx", "fx_5_0", SlimDX.D3DCompiler.ShaderFlags.EnableStrictness, SlimDX.D3DCompiler.EffectFlags.None); effect = new SlimDX.Direct3D11.Effect(device.Handle, shaderByteCode); // create triangle vertex data, making sure to rewind the stream afterward var verticesTriangle = new SlimDX.DataStream(30 * 3, true, true); verticesTriangle.Write(new SlimDX.Vector3(0.0f, 0.5f, 0.5f)); verticesTriangle.Write(new SlimDX.Color4(1.0f, 0.0f, 0.0f, 1.0f)); verticesTriangle.Write(new SlimDX.Vector3(0.5f, -0.5f, 0.5f)); verticesTriangle.Write(new SlimDX.Color4(0.0f, 1.0f, 0.0f, 1.0f)); verticesTriangle.Write(new SlimDX.Vector3(-0.5f, -0.5f, 0.5f)); verticesTriangle.Write(new SlimDX.Color4(0.0f, 0.0f, 1.0f, 1.0f)); verticesTriangle.Position = 0; // create the triangle vertex layout and buffer var inputElements = new SlimDX.Direct3D11.InputElement[] { new SlimDX.Direct3D11.InputElement("POSITION", 0, SlimDX.DXGI.Format.R32G32B32A32_Float, 0, 0), new SlimDX.Direct3D11.InputElement("COLOR",0,SlimDX.DXGI.Format.R32G32B32A32_Float,16,0) }; var layoutColor = new SlimDX.Direct3D11.InputLayout(device.Handle, effect.GetTechniqueByName("Color").GetPassByIndex(0).Description.Signature, inputElements); var vertexBufferColor = new SlimDX.Direct3D11.Buffer(device.Handle, verticesTriangle, (int)verticesTriangle.Length, SlimDX.Direct3D11.ResourceUsage.Default, SlimDX.Direct3D11.BindFlags.VertexBuffer, SlimDX.Direct3D11.CpuAccessFlags.None, SlimDX.Direct3D11.ResourceOptionFlags.None, 0); verticesTriangle.Close(); // create text vertex data, making sure to rewind the stream afterward // Top Left of screen is -1, +1 // Bottom Right of screen is +1, -1 var verticesText = new SlimDX.DataStream(30 * 4, true, true); verticesText.Write(new SlimDX.Vector3(-1, 1, 0)); verticesText.Write(new SlimDX.Vector2(0, 0f)); verticesText.Write(new SlimDX.Vector3(1, 1, 0)); verticesText.Write(new SlimDX.Vector2(1, 0)); verticesText.Write(new SlimDX.Vector3(-1, -1, 0)); verticesText.Write(new SlimDX.Vector2(0, 1)); verticesText.Write(new SlimDX.Vector3(1, -1, 0)); verticesText.Write(new SlimDX.Vector2(1, 1)); verticesText.Position = 0; // create the text vertex layout and buffer layoutText = new SlimDX.Direct3D11.InputLayout(device.Handle, effect.GetTechniqueByName("Text").GetPassByIndex(0).Description.Signature, inputElements); vertexBufferText = new SlimDX.Direct3D11.Buffer(device.Handle, verticesText, (int)verticesText.Length, SlimDX.Direct3D11.ResourceUsage.Default, SlimDX.Direct3D11.BindFlags.VertexBuffer, SlimDX.Direct3D11.CpuAccessFlags.None, SlimDX.Direct3D11.ResourceOptionFlags.None, 0); verticesText.Close(); } } }
public void Save(SlimDX.DXGI.Adapter adapter, DX11Texture2D texture, string filename, ImageFileFormat format) { //If we're being re-used, called recycle if (this.Completed) { this.Recycle(); } FFilename = filename; try { //log the render device context if (this.FAssets.RenderDeviceContext != texture.Resource.Device.ImmediateContext) { this.FAssets.Dispose(); this.FAssets.RenderDeviceContext = texture.Resource.Device.ImmediateContext; this.FAssets.RenderDevice = texture.Resource.Device; } //allocate textures if (FAssets.Description != texture.Description) { this.FAssets.Dispose(); FAssets.Description = texture.Description; FAssets.SharedDescription = texture.Description; { FAssets.SharedDescription.Usage = ResourceUsage.Default; FAssets.SharedDescription.OptionFlags |= ResourceOptionFlags.Shared; } FAssets.SharedTextureOnRenderDevice = new Texture2D(this.FAssets.RenderDevice, FAssets.SharedDescription); } //copy input texture to shared texture { this.FAssets.RenderDeviceContext.CopyResource(texture.Resource, FAssets.SharedTextureOnRenderDevice); } //create a device/context for saving if (FAssets.SaveDevice == null) { #if DEBUG FAssets.SaveDevice = new SlimDX.Direct3D11.Device(adapter, DeviceCreationFlags.Debug); #else FAssets.SaveDevice = new SlimDX.Direct3D11.Device(adapter); #endif FAssets.SaveDeviceContext = FAssets.SaveDevice.ImmediateContext; } //flush the immediate context to ensure that our shared texture is available { var queryDescription = new QueryDescription(QueryType.Event, QueryFlags.None); var query = new Query(FAssets.RenderDevice, queryDescription); FAssets.RenderDeviceContext.Flush(); FAssets.RenderDeviceContext.End(query); var result = FAssets.RenderDeviceContext.GetData <bool>(query); while (!result) { result = FAssets.RenderDeviceContext.GetData <bool>(query); Thread.Sleep(1); } } //create the textures on saving device if (FAssets.SharedTextureOnSaveDevice == null) { SlimDX.DXGI.Resource r = new SlimDX.DXGI.Resource(FAssets.SharedTextureOnRenderDevice); FAssets.SharedTextureOnSaveDevice = FAssets.SaveDevice.OpenSharedResource <Texture2D>(r.SharedHandle); var stagingTextureDescription = texture.Description; { stagingTextureDescription.Usage = ResourceUsage.Default; } FAssets.StagingTextureOnSaveDevice = new Texture2D(FAssets.SaveDevice, stagingTextureDescription); } //copy the shared texture into a staging texture (actually for our purpose, we will not use an actual staging texture since we use SaveTextureToFile which handles staging for us) FAssets.SaveDeviceContext.CopyResource(FAssets.SharedTextureOnSaveDevice, FAssets.StagingTextureOnSaveDevice); this.FThread = new Thread(() => { try { //gain rights to write to file (new FileIOPermission(FileIOPermissionAccess.Write, filename)).Demand(); //perform read back and save in thread try { var directory = Path.GetDirectoryName(filename); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } FeralTic.DX11.Resources.TextureLoader.NativeMethods.SaveTextureToFile(FAssets.SaveDevice.ComPointer , FAssets.SaveDeviceContext.ComPointer , FAssets.StagingTextureOnSaveDevice.ComPointer , filename , (int)format); } catch (Exception e) { throw (new Exception("SaveTextureToFile failed : " + e.Message)); } this.CompletedBang = true; this.Completed = true; this.Status = "OK"; this.Success = true; } catch (Exception e) { this.Completed = true; this.Status = e.Message; this.Success = false; } }); this.FThread.Name = "DX11 read"; this.FThread.Start(); } catch (Exception e) { this.Completed = true; this.Success = false; this.Status = e.Message; } }
public void Evaluate(int SpreadMax) { if (this.FBufferIn.IsConnected) { if (this.RenderRequest != null) { this.RenderRequest(this, this.FHost); } if (this.AssignedContext == null) { this.SetNull(); return; } this.FPointer.SliceCount = SpreadMax; DX11RenderContext context = this.AssignedContext; try { if (this.FBufferIn[0].Contains(context)) { var inputBuffer = this.FBufferIn[0][context].Buffer; if (this.currentBuffer != null) { if (this.currentDescription != inputBuffer.Description) { this.currentBuffer.Dispose(); this.currentBuffer = null; this.sharedResource.Dispose(); this.sharedResource = null; } } //As it can come from dynamic, make sure to allow share put in default pool and deny cpu access if (this.currentBuffer == null) { var desc = inputBuffer.Description; desc.BindFlags = BindFlags.ShaderResource; //This is important, as resource needs read access later on, it's not only a copy, if not set other side will not be able to create srv desc.OptionFlags |= ResourceOptionFlags.Shared; desc.Usage = ResourceUsage.Default; desc.CpuAccessFlags = CpuAccessFlags.None; this.currentBuffer = new SlimDX.Direct3D11.Buffer(context.Device, desc); this.sharedResource = new SlimDX.DXGI.Resource(this.currentBuffer); this.currentDescription = inputBuffer.Description; this.FPointer[0] = this.sharedResource.SharedHandle.ToString(); } this.AssignedContext.CurrentDeviceContext.CopyResource(inputBuffer, this.currentBuffer); if (this.flush[0]) { this.AssignedContext.CurrentDeviceContext.Flush(); } } else { this.SetDefault(0); } } catch { this.SetDefault(0); } } else { this.SetNull(); } }