OSDN Git Service

DXGIDeviceManager を追加し、D3DDeivce を共有化。
authorくまかみ工房 <kumakamikoubou@gmail.com>
Sat, 17 Sep 2016 15:44:03 +0000 (00:44 +0900)
committerくまかみ工房 <kumakamikoubou@gmail.com>
Sat, 17 Sep 2016 15:44:03 +0000 (00:44 +0900)
FDK24/ApplicationFormBase.cs
FDK24/FDK24.csproj
FDK24/メディア/テクスチャ.cs
FDK24/メディア/デバイスリソース.cs
FDK24/同期/AutoD3DDeviceLock.cs [new file with mode: 0644]
StrokeStyleT/ApplicationForm.cs

index 118a09a..e9b069a 100644 (file)
@@ -76,11 +76,6 @@ namespace FDK
                        {
                                return; // まだ初期化されてない(ので何もしない)。
                        }
-                       if( null == this.デバイスリソース.D3DDevice )
-                       {
-                               Trace.WriteLine( "D3Dデバイスが null です。" );
-                               return;
-                       }
                        if( this.WindowState == FormWindowState.Minimized )
                        {
                                Trace.WriteLine( "最小化されました。" );
index 3b5027c..99c0172 100644 (file)
     <Compile Include="フォルダ.cs" />
     <Compile Include="メディア\テクスチャ.cs" />
     <Compile Include="メディア\デバイスリソース.cs" />
+    <Compile Include="同期\AutoD3DDeviceLock.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />
index 63adadf..040ae8b 100644 (file)
@@ -11,93 +11,97 @@ namespace FDK.メディア
 
                public static void 共有リソースを作成する( FDK.メディア.デバイスリソース dr )
                {
-                       #region " 頂点シェーダ "
-                       //----------------
-                       var シェーダコンパイルのオプション =
+                       var d3dDevice = (SharpDX.Direct3D11.Device) null;
+                       using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
+                       {
+                               #region " 頂点シェーダ "
+                               //----------------
+                               var シェーダコンパイルのオプション =
                                SharpDX.D3DCompiler.ShaderFlags.Debug |
                                SharpDX.D3DCompiler.ShaderFlags.SkipOptimization |
                                SharpDX.D3DCompiler.ShaderFlags.EnableStrictness |
                                SharpDX.D3DCompiler.ShaderFlags.PackMatrixColumnMajor;
 
-                       // シェーダコードをコンパイルする。
-                       using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
-                               FDK.Properties.Resources.テクスチャ用シェーダコード,
-                               "VS", "vs_4_0", シェーダコンパイルのオプション ) )
-                       {
-                               // 頂点シェーダを生成する。
-                               テクスチャ.VertexShader = new SharpDX.Direct3D11.VertexShader( dr.D3DDevice, code );
-                       }
-                       //----------------
-                       #endregion
-                       #region " ピクセルシェーダ "
-                       //----------------
-                       // シェーダコードをコンパイルする。
-                       using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
-                               FDK.Properties.Resources.テクスチャ用シェーダコード,
-                               "PS", "ps_4_0", シェーダコンパイルのオプション ) )
-                       {
-                               // ピクセルシェーダを作成する。
-                               テクスチャ.PixelShader = new SharpDX.Direct3D11.PixelShader( dr.D3DDevice, code );
+                               // シェーダコードをコンパイルする。
+                               using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
+                                       FDK.Properties.Resources.テクスチャ用シェーダコード,
+                                       "VS", "vs_4_0", シェーダコンパイルのオプション ) )
+                               {
+                                       // 頂点シェーダを生成する。
+                                       テクスチャ.VertexShader = new SharpDX.Direct3D11.VertexShader( d3dDevice, code );
+                               }
+                               //----------------
+                               #endregion
+                               #region " ピクセルシェーダ "
+                               //----------------
+                               // シェーダコードをコンパイルする。
+                               using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
+                                       FDK.Properties.Resources.テクスチャ用シェーダコード,
+                                       "PS", "ps_4_0", シェーダコンパイルのオプション ) )
+                               {
+                                       // ピクセルシェーダを作成する。
+                                       テクスチャ.PixelShader = new SharpDX.Direct3D11.PixelShader( d3dDevice, code );
+                               }
+                               //----------------
+                               #endregion
+                               #region " ブレンドステート "
+                               //----------------
+                               var BlendState = new SharpDX.Direct3D11.BlendStateDescription() {
+                                       AlphaToCoverageEnable = false,  // アルファマスクで透過する(するならZバッファ必須)
+                                       IndependentBlendEnable = false, // 個別設定。false なら BendStateDescription.RenderTarget[0] だけが有効で、[1~7] は無視される。
+                               };
+                               BlendState.RenderTarget[ 0 ].IsBlendEnabled = true; // true ならブレンディングが有効。
+                               BlendState.RenderTarget[ 0 ].RenderTargetWriteMask = SharpDX.Direct3D11.ColorWriteMaskFlags.All;        // RGBA の書き込みマスク。
+
+                               // アルファ値のブレンディング設定 ... 特になし
+                               BlendState.RenderTarget[ 0 ].SourceAlphaBlend = SharpDX.Direct3D11.BlendOption.One;
+                               BlendState.RenderTarget[ 0 ].DestinationAlphaBlend = SharpDX.Direct3D11.BlendOption.Zero;
+                               BlendState.RenderTarget[ 0 ].AlphaBlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
+
+                               // 色値のブレンディング設定 ... アルファ強度に応じた透明合成(テクスチャのアルファ値は、テクスチャのアルファ×ピクセルシェーダでの全体アルファとする(HLSL参照))
+                               BlendState.RenderTarget[ 0 ].SourceBlend = SharpDX.Direct3D11.BlendOption.SourceAlpha;
+                               BlendState.RenderTarget[ 0 ].DestinationBlend = SharpDX.Direct3D11.BlendOption.InverseSourceAlpha;
+                               BlendState.RenderTarget[ 0 ].BlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
+
+                               // ブレンドステートを作成する。
+                               テクスチャ.BlendState = new SharpDX.Direct3D11.BlendState( d3dDevice, BlendState );
+                               //----------------
+                               #endregion
+                               #region " ラスタライザステート "
+                               //----------------
+                               var RSDesc = new SharpDX.Direct3D11.RasterizerStateDescription() {
+                                       FillMode = SharpDX.Direct3D11.FillMode.Solid,   // 普通に描画する
+                                       CullMode = SharpDX.Direct3D11.CullMode.None,    // 両面を描画する
+                                       IsFrontCounterClockwise = false,    // 時計回りが表面
+                                       DepthBias = 0,
+                                       DepthBiasClamp = 0,
+                                       SlopeScaledDepthBias = 0,
+                                       IsDepthClipEnabled = true,
+                                       IsScissorEnabled = false,
+                                       IsMultisampleEnabled = false,
+                                       IsAntialiasedLineEnabled = false,
+                               };
+                               テクスチャ.RasterizerState = new SharpDX.Direct3D11.RasterizerState( d3dDevice, RSDesc );
+                               //----------------
+                               #endregion
+                               #region " サンプラーステート "
+                               //----------------
+                               var descSampler = new SharpDX.Direct3D11.SamplerStateDescription() {
+                                       Filter = SharpDX.Direct3D11.Filter.Anisotropic,
+                                       AddressU = SharpDX.Direct3D11.TextureAddressMode.Wrap,
+                                       AddressV = SharpDX.Direct3D11.TextureAddressMode.Wrap,
+                                       AddressW = SharpDX.Direct3D11.TextureAddressMode.Wrap,
+                                       MipLodBias = 0.0f,
+                                       MaximumAnisotropy = 2,
+                                       ComparisonFunction = SharpDX.Direct3D11.Comparison.Never,
+                                       BorderColor = new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ),
+                                       MinimumLod = float.MinValue,
+                                       MaximumLod = float.MaxValue,
+                               };
+                               テクスチャ.SamplerState = new SharpDX.Direct3D11.SamplerState( d3dDevice, descSampler );
+                               //----------------
+                               #endregion
                        }
-                       //----------------
-                       #endregion
-                       #region " ブレンドステート "
-                       //----------------
-                       var BlendState = new SharpDX.Direct3D11.BlendStateDescription() {
-                               AlphaToCoverageEnable = false,  // アルファマスクで透過する(するならZバッファ必須)
-                               IndependentBlendEnable = false, // 個別設定。false なら BendStateDescription.RenderTarget[0] だけが有効で、[1~7] は無視される。
-                       };
-                       BlendState.RenderTarget[ 0 ].IsBlendEnabled = true; // true ならブレンディングが有効。
-                       BlendState.RenderTarget[ 0 ].RenderTargetWriteMask = SharpDX.Direct3D11.ColorWriteMaskFlags.All;        // RGBA の書き込みマスク。
-
-                       // アルファ値のブレンディング設定 ... 特になし
-                       BlendState.RenderTarget[ 0 ].SourceAlphaBlend = SharpDX.Direct3D11.BlendOption.One;
-                       BlendState.RenderTarget[ 0 ].DestinationAlphaBlend = SharpDX.Direct3D11.BlendOption.Zero;
-                       BlendState.RenderTarget[ 0 ].AlphaBlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
-
-                       // 色値のブレンディング設定 ... アルファ強度に応じた透明合成(テクスチャのアルファ値は、テクスチャのアルファ×ピクセルシェーダでの全体アルファとする(HLSL参照))
-                       BlendState.RenderTarget[ 0 ].SourceBlend = SharpDX.Direct3D11.BlendOption.SourceAlpha;
-                       BlendState.RenderTarget[ 0 ].DestinationBlend = SharpDX.Direct3D11.BlendOption.InverseSourceAlpha;
-                       BlendState.RenderTarget[ 0 ].BlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
-
-                       // ブレンドステートを作成する。
-                       テクスチャ.BlendState = new SharpDX.Direct3D11.BlendState( dr.D3DDevice, BlendState );
-                       //----------------
-                       #endregion
-                       #region " ラスタライザステート "
-                       //----------------
-                       var RSDesc = new SharpDX.Direct3D11.RasterizerStateDescription() {
-                               FillMode = SharpDX.Direct3D11.FillMode.Solid,   // 普通に描画する
-                               CullMode = SharpDX.Direct3D11.CullMode.None,    // 両面を描画する
-                               IsFrontCounterClockwise = false,    // 時計回りが表面
-                               DepthBias = 0,
-                               DepthBiasClamp = 0,
-                               SlopeScaledDepthBias = 0,
-                               IsDepthClipEnabled = true,
-                               IsScissorEnabled = false,
-                               IsMultisampleEnabled = false,
-                               IsAntialiasedLineEnabled = false,
-                       };
-                       テクスチャ.RasterizerState = new SharpDX.Direct3D11.RasterizerState( dr.D3DDevice, RSDesc );
-                       //----------------
-                       #endregion
-                       #region " サンプラーステート "
-                       //----------------
-                       var descSampler = new SharpDX.Direct3D11.SamplerStateDescription() {
-                               Filter = SharpDX.Direct3D11.Filter.Anisotropic,
-                               AddressU = SharpDX.Direct3D11.TextureAddressMode.Wrap,
-                               AddressV = SharpDX.Direct3D11.TextureAddressMode.Wrap,
-                               AddressW = SharpDX.Direct3D11.TextureAddressMode.Wrap,
-                               MipLodBias = 0.0f,
-                               MaximumAnisotropy = 2,
-                               ComparisonFunction = SharpDX.Direct3D11.Comparison.Never,
-                               BorderColor = new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ),
-                               MinimumLod = float.MinValue,
-                               MaximumLod = float.MaxValue,
-                       };
-                       テクスチャ.SamplerState = new SharpDX.Direct3D11.SamplerState( dr.D3DDevice, descSampler );
-                       //----------------
-                       #endregion
                }
                public static void 共有リソースを解放する()
                {
@@ -128,25 +132,29 @@ namespace FDK.メディア
                }
                protected override void On活性化( デバイスリソース dr )
                {
-                       #region " 定数バッファ "
-                       //----------------
-                       var cBufferDesc = new SharpDX.Direct3D11.BufferDescription() {
-                               Usage = SharpDX.Direct3D11.ResourceUsage.Dynamic,   // 動的使用法
-                               BindFlags = SharpDX.Direct3D11.BindFlags.ConstantBuffer,    // 定数バッファ
-                               CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.Write,   // CPUから書き込む
-                               OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
-                               SizeInBytes = SharpDX.Utilities.SizeOf<ST定数バッファの転送元データ>(),   // バッファサイズ
-                               StructureByteStride = 0,
-                       };
-                       this.ConstantBuffer = new SharpDX.Direct3D11.Buffer( dr.D3DDevice, cBufferDesc );
-                       //----------------
-                       #endregion
-                       #region " シェーダーリソースビュー "
-                       //----------------
-                       this.ShaderResourceView = FDK.Utilities.CreateShaderResourceViewFromFile(
-                               dr.D3DDevice, "テスト用テクスチャ画像.jpg", out this.ShaderResourceViewSize );
-                       //----------------
-                       #endregion
+                       var d3dDevice = (SharpDX.Direct3D11.Device) null;
+                       using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
+                       {
+                               #region " 定数バッファ "
+                               //----------------
+                               var cBufferDesc = new SharpDX.Direct3D11.BufferDescription() {
+                                       Usage = SharpDX.Direct3D11.ResourceUsage.Dynamic,   // 動的使用法
+                                       BindFlags = SharpDX.Direct3D11.BindFlags.ConstantBuffer,    // 定数バッファ
+                                       CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.Write,   // CPUから書き込む
+                                       OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
+                                       SizeInBytes = SharpDX.Utilities.SizeOf<ST定数バッファの転送元データ>(),   // バッファサイズ
+                                       StructureByteStride = 0,
+                               };
+                               this.ConstantBuffer = new SharpDX.Direct3D11.Buffer( d3dDevice, cBufferDesc );
+                               //----------------
+                               #endregion
+                               #region " シェーダーリソースビュー "
+                               //----------------
+                               this.ShaderResourceView = FDK.Utilities.CreateShaderResourceViewFromFile(
+                                       d3dDevice, FDK.フォルダ.絶対パスに含まれるフォルダ変数を展開して返す( this.画像ファイルパス ), out this.ShaderResourceViewSize );
+                               //----------------
+                               #endregion
+                       }
                }
                protected override void On非活性化( デバイスリソース dr )
                {
@@ -156,78 +164,82 @@ namespace FDK.メディア
                /// <param name="転送元矩形">テクスチャ座標(値域0~1)で指定する。</param>
                public void 進行描画する( デバイスリソース dr, SharpDX.Matrix ワールド行列変換, SharpDX.RectangleF? 転送元矩形 = null )
                {
-                       var d3dContext = dr.D3DDevice.ImmediateContext;
-                       
-                       #region " 定数バッファを更新する。"
-                       //----------------
+                       var d3dDevice = (SharpDX.Direct3D11.Device) null;
+                       using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
                        {
-                               // ワールド変換行列
-                               ワールド行列変換.Transpose();    // 転置
-                               this.定数バッファの転送元データ.World = ワールド行列変換;
-
-                               // ビュー変換行列
-                               this.定数バッファの転送元データ.View = dr.ビュー変換行列;
-
-                               // 射影変換行列
-                               this.定数バッファの転送元データ.Projection = dr.射影変換行列;
-
-                               // 描画元矩形
-                               if( null == 転送元矩形 )
-                                       転送元矩形 = new SharpDX.RectangleF( 0f, 0f, 1f, 1f );
-                               this.定数バッファの転送元データ.TexLeft = 転送元矩形.Value.Left;
-                               this.定数バッファの転送元データ.TexTop = 転送元矩形.Value.Top;
-                               this.定数バッファの転送元データ.TexRight = 転送元矩形.Value.Right;
-                               this.定数バッファの転送元データ.TexBottom = 転送元矩形.Value.Bottom;
-
-                               // アルファ
-                               this.定数バッファの転送元データ.TexAlpha = this.不透明度;
-                               this.定数バッファの転送元データ.dummy1 = 0f;
-                               this.定数バッファの転送元データ.dummy2 = 0f;
-                               this.定数バッファの転送元データ.dummy3 = 0f;
-
-                               // 定数バッファへの書き込み
-                               var dataBox = d3dContext.MapSubresource(
-                                       resourceRef: this.ConstantBuffer,
-                                       subresource: 0,
-                                       mapType: SharpDX.Direct3D11.MapMode.WriteDiscard,
-                                       mapFlags: SharpDX.Direct3D11.MapFlags.None );
-                               SharpDX.Utilities.Write( dataBox.DataPointer, ref this.定数バッファの転送元データ );
-                               d3dContext.UnmapSubresource( this.ConstantBuffer, 0 );
+                               var d3dContext = d3dDevice.ImmediateContext;
+
+                               #region " 定数バッファを更新する。"
+                               //----------------
+                               {
+                                       // ワールド変換行列
+                                       ワールド行列変換.Transpose();    // 転置
+                                       this.定数バッファの転送元データ.World = ワールド行列変換;
+
+                                       // ビュー変換行列
+                                       this.定数バッファの転送元データ.View = dr.ビュー変換行列;
+
+                                       // 射影変換行列
+                                       this.定数バッファの転送元データ.Projection = dr.射影変換行列;
+
+                                       // 描画元矩形
+                                       if( null == 転送元矩形 )
+                                               転送元矩形 = new SharpDX.RectangleF( 0f, 0f, 1f, 1f );
+                                       this.定数バッファの転送元データ.TexLeft = 転送元矩形.Value.Left;
+                                       this.定数バッファの転送元データ.TexTop = 転送元矩形.Value.Top;
+                                       this.定数バッファの転送元データ.TexRight = 転送元矩形.Value.Right;
+                                       this.定数バッファの転送元データ.TexBottom = 転送元矩形.Value.Bottom;
+
+                                       // アルファ
+                                       this.定数バッファの転送元データ.TexAlpha = this.不透明度;
+                                       this.定数バッファの転送元データ.dummy1 = 0f;
+                                       this.定数バッファの転送元データ.dummy2 = 0f;
+                                       this.定数バッファの転送元データ.dummy3 = 0f;
+
+                                       // 定数バッファへの書き込み
+                                       var dataBox = d3dContext.MapSubresource(
+                                               resourceRef: this.ConstantBuffer,
+                                               subresource: 0,
+                                               mapType: SharpDX.Direct3D11.MapMode.WriteDiscard,
+                                               mapFlags: SharpDX.Direct3D11.MapFlags.None );
+                                       SharpDX.Utilities.Write( dataBox.DataPointer, ref this.定数バッファの転送元データ );
+                                       d3dContext.UnmapSubresource( this.ConstantBuffer, 0 );
+                               }
+                               //----------------
+                               #endregion
+                               #region " 3Dパイプラインを設定する。"
+                               //----------------
+                               // 入力アセンブラ
+                               d3dContext.InputAssembler.InputLayout = null;
+                               d3dContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleStrip;
+
+                               // 頂点シェーダ
+                               d3dContext.VertexShader.Set( テクスチャ.VertexShader );
+                               d3dContext.VertexShader.SetConstantBuffers( 0, this.ConstantBuffer );
+
+                               // ジオメトリシェーダ
+                               d3dContext.GeometryShader.Set( null );
+
+                               // ラスタライザ
+                               d3dContext.Rasterizer.SetViewports( dr.D3DViewPort );
+                               d3dContext.Rasterizer.State = テクスチャ.RasterizerState;
+
+                               // ピクセルシェーダ
+                               d3dContext.PixelShader.Set( テクスチャ.PixelShader );
+                               d3dContext.PixelShader.SetConstantBuffers( 0, this.ConstantBuffer );
+                               d3dContext.PixelShader.SetShaderResources( 0, 1, this.ShaderResourceView );
+                               d3dContext.PixelShader.SetSamplers( 0, 1, テクスチャ.SamplerState );
+
+                               // 出力マージャ
+                               d3dContext.OutputMerger.SetTargets( dr.D3DDepthStencilView, dr.D3DRenderTargetView );
+                               d3dContext.OutputMerger.SetBlendState( テクスチャ.BlendState, new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ), -1 );
+                               d3dContext.OutputMerger.SetDepthStencilState( dr.D3DDepthStencilState, 0 );
+                               //----------------
+                               #endregion
+
+                               // 頂点バッファとインデックスバッファを使わずに 4 つの頂点を描画する。
+                               d3dContext.Draw( vertexCount: 4, startVertexLocation: 0 );
                        }
-                       //----------------
-                       #endregion
-                       #region " 3Dパイプラインを設定する。"
-                       //----------------
-                       // 入力アセンブラ
-                       d3dContext.InputAssembler.InputLayout = null;
-                       d3dContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleStrip;
-
-                       // 頂点シェーダ
-                       d3dContext.VertexShader.Set( テクスチャ.VertexShader );
-                       d3dContext.VertexShader.SetConstantBuffers( 0, this.ConstantBuffer );
-
-                       // ジオメトリシェーダ
-                       d3dContext.GeometryShader.Set( null );
-
-                       // ラスタライザ
-                       d3dContext.Rasterizer.SetViewports( dr.D3DViewPort );
-                       d3dContext.Rasterizer.State = テクスチャ.RasterizerState;
-
-                       // ピクセルシェーダ
-                       d3dContext.PixelShader.Set( テクスチャ.PixelShader );
-                       d3dContext.PixelShader.SetConstantBuffers( 0, this.ConstantBuffer );
-                       d3dContext.PixelShader.SetShaderResources( 0, 1, this.ShaderResourceView );
-                       d3dContext.PixelShader.SetSamplers( 0, 1, テクスチャ.SamplerState );
-
-                       // 出力マージャ
-                       d3dContext.OutputMerger.SetTargets( dr.D3DDepthStencilView, dr.D3DRenderTargetView );
-                       d3dContext.OutputMerger.SetBlendState( テクスチャ.BlendState, new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ), -1 );
-                       d3dContext.OutputMerger.SetDepthStencilState( dr.D3DDepthStencilState, 0 );
-                       //----------------
-                       #endregion
-
-                       // 頂点バッファとインデックスバッファを使わずに 4 つの頂点を描画する。
-                       d3dContext.Draw( vertexCount: 4, startVertexLocation: 0 );
                }
 
                protected string 画像ファイルパス = null;
index a96359a..b9cb985 100644 (file)
@@ -37,7 +37,7 @@ namespace FDK.メディア
                                return mat;
                        }
                }
-               public SharpDX.Direct3D11.Device D3DDevice => this.bs_D3DDevice;
+               public SharpDX.MediaFoundation.DXGIDeviceManager DXGIDeviceManager => this.bs_DXGIDeviceManager;
                public SharpDX.DXGI.SwapChain SwapChain => this.bs_SwapChain;
                public SharpDX.Direct3D11.RenderTargetView D3DRenderTargetView => this.bs_D3DRenderTargetView;
                public SharpDX.Mathematics.Interop.RawViewportF[] D3DViewPort => this.bs_D3DViewPort;
@@ -58,7 +58,14 @@ namespace FDK.メディア
                        Debug.Assert( ( 0f < this.物理画面サイズpx.Width ) && ( 0f < this.物理画面サイズpx.Height ) );
                        Debug.Assert( IntPtr.Zero != this.ウィンドウハンドル );
 
-                       #region " デバイス、スワップチェーンを作成する。"
+                       var d3dDevice = (SharpDX.Direct3D11.Device) null;
+
+                       #region " DXGIDeviceManager を作成する。"
+                       //-----------------
+                       this.bs_DXGIDeviceManager = new SharpDX.MediaFoundation.DXGIDeviceManager();
+                       //-----------------
+                       #endregion
+                       #region " D3Dデバイス、スワップチェーンを作成する。"
                        //----------------
                        // スワップチェーン desc
                        var swapChainDesc = new SharpDX.DXGI.SwapChainDescription() {
@@ -87,67 +94,101 @@ namespace FDK.メディア
                                SharpDX.Direct3D11.DeviceCreationFlags.None,
                                featureLevels,
                                swapChainDesc,
-                               out this.bs_D3DDevice,
+                               out d3dDevice,
                                out this.bs_SwapChain );
 
                        Trace.WriteLine( "D3Dデバイスとスワップチェーンを生成しました。" );
-                       Trace.WriteLine( $"機能レベル: {this.bs_D3DDevice.FeatureLevel.ToString()}" );
+                       Trace.WriteLine( $"機能レベル: {d3dDevice.FeatureLevel.ToString()}" );
                        //----------------
                        #endregion
-                       #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。"
-                       //----------------
-                       using( var factory = this.bs_SwapChain.GetParent<SharpDX.DXGI.Factory>() )
+
+                       using( d3dDevice )
                        {
-                               factory.MakeWindowAssociation( ウィンドウハンドル, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll );
-                       }
-                       //----------------
-                       #endregion
-                       #region " 深度ステンシルステート "
-                       //----------------
-                       var DepthSencil = new SharpDX.Direct3D11.DepthStencilStateDescription() {
-                               IsDepthEnabled = true,  // 深度テストあり
-                               DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.All,     // 書き込む
-                               DepthComparison = SharpDX.Direct3D11.Comparison.Less,   // 手前の物体を描画
-                               IsStencilEnabled = false,   // ステンシルテストなし。
-                               StencilReadMask = 0,    // ステンシル読み込みマスク。
-                               StencilWriteMask = 0,   // ステンシル書き込みマスク。
+                               #region " D3DDevice が ID3D11VideoDevice を実装してないならエラー。(Win8以降のPCでは実装されているはず。) "
+                               //-----------------
+                               using( var videoDevice = d3dDevice.QueryInterfaceOrNull<SharpDX.Direct3D11.VideoDevice>() )
+                               {
+                                       if( null == videoDevice )
+                                               throw new FDKException( "Direct3D11デバイスが、ID3D11VideoDevice をサポートしていません。" );
+                               }
+                               //-----------------
+                               #endregion
+                               #region " マルチスレッドモードを ON に設定する。DXVAを使う場合は必須。"
+                               //-----------------
+                               using( var multithread = d3dDevice.QueryInterfaceOrNull<SharpDX.Direct3D.DeviceMultithread>() )
+                               {
+                                       if( null == multithread )
+                                               throw new FDKException( "Direct3D11デバイスが、ID3D10Multithread をサポートしていません。" );
 
-                               // 面が表を向いている場合のステンシル・テストの設定
-                               FrontFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
-                                       FailOperation = SharpDX.Direct3D11.StencilOperation.Keep,   // 維持
-                                       DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep,  // 維持
-                                       PassOperation = SharpDX.Direct3D11.StencilOperation.Keep,   // 維持
-                                       Comparison = SharpDX.Direct3D11.Comparison.Never,   // 常に失敗
-                               },
+                                       multithread.SetMultithreadProtected( true );
+                               }
+                               //-----------------
+                               #endregion
+                               #region " DXGIデバイスマネージャに D3Dデバイスを登録する。"
+                               //-----------------
+                               this.DXGIDeviceManager.ResetDevice( d3dDevice );
+                               //-----------------
+                               #endregion
+                               #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。"
+                               //----------------
+                               using( var factory = this.bs_SwapChain.GetParent<SharpDX.DXGI.Factory>() )
+                               {
+                                       factory.MakeWindowAssociation( ウィンドウハンドル, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll );
+                               }
+                               //----------------
+                               #endregion
+                               #region " 深度ステンシルステート "
+                               //----------------
+                               var DepthSencil = new SharpDX.Direct3D11.DepthStencilStateDescription() {
+                                       IsDepthEnabled = true,  // 深度テストあり
+                                       DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.All,     // 書き込む
+                                       DepthComparison = SharpDX.Direct3D11.Comparison.Less,   // 手前の物体を描画
+                                       IsStencilEnabled = false,   // ステンシルテストなし。
+                                       StencilReadMask = 0,    // ステンシル読み込みマスク。
+                                       StencilWriteMask = 0,   // ステンシル書き込みマスク。
 
-                               // 面が裏を向いている場合のステンシル・テストの設定
-                               BackFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
-                                       FailOperation = SharpDX.Direct3D11.StencilOperation.Keep,   // 維持
-                                       DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep,  // 維持
-                                       PassOperation = SharpDX.Direct3D11.StencilOperation.Keep,   // 維持
-                                       Comparison = SharpDX.Direct3D11.Comparison.Always,  // 常に成功
-                               },
-                       };
-                       this.bs_D3DDepthStencilState = new SharpDX.Direct3D11.DepthStencilState( this.bs_D3DDevice, DepthSencil );
-                       //----------------
-                       #endregion
+                                       // 面が表を向いている場合のステンシル・テストの設定
+                                       FrontFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
+                                               FailOperation = SharpDX.Direct3D11.StencilOperation.Keep,   // 維持
+                                               DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep,  // 維持
+                                               PassOperation = SharpDX.Direct3D11.StencilOperation.Keep,   // 維持
+                                               Comparison = SharpDX.Direct3D11.Comparison.Never,   // 常に失敗
+                                       },
+
+                                       // 面が裏を向いている場合のステンシル・テストの設定
+                                       BackFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
+                                               FailOperation = SharpDX.Direct3D11.StencilOperation.Keep,   // 維持
+                                               DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep,  // 維持
+                                               PassOperation = SharpDX.Direct3D11.StencilOperation.Keep,   // 維持
+                                               Comparison = SharpDX.Direct3D11.Comparison.Always,  // 常に成功
+                                       },
+                               };
+                               this.bs_D3DDepthStencilState = new SharpDX.Direct3D11.DepthStencilState( d3dDevice, DepthSencil );
+                               //----------------
+                               #endregion
+                       }
 
                        this.サイズに依存するリソースを作成する();
                }
                public void すべてのリソースを解放する()
                {
-                       // デバイスステートをクリアする。
-                       this.bs_D3DDevice?.ImmediateContext?.ClearState();
+                       var d3dDevice = (SharpDX.Direct3D11.Device) null;
+                       using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
+                       {
+                               // デバイスステートをクリアする。
+                               d3dDevice.ImmediateContext?.ClearState();
 
-                       // スワップチェインをウインドウモードにする。
-                       this.bs_SwapChain?.SetFullscreenState( fullscreen: false, targetRef: null );
+                               // スワップチェインをウインドウモードにする。
+                               this.bs_SwapChain?.SetFullscreenState( fullscreen: false, targetRef: null );
 
-                       this.サイズに依存するリソースを解放する();
+                               this.サイズに依存するリソースを解放する();
 
-                       // 取得したインターフェイスの開放
-                       this.bs_D3DDepthStencilState?.Dispose();
-                       this.bs_SwapChain?.Dispose();
-                       this.bs_D3DDevice?.Dispose();
+                               // 取得したインターフェイスの開放
+                               this.bs_D3DDepthStencilState?.Dispose();
+                               this.bs_SwapChain?.Dispose();
+                               this.bs_DXGIDeviceManager?.ResetDevice( null );
+                               this.bs_DXGIDeviceManager?.Dispose();
+                       }
                }
                public void サイズに依存するリソースを作成する()
                {
@@ -166,83 +207,90 @@ namespace FDK.メディア
                        // 新しいサイズになったバックバッファを取得して、リソースを作成する。
                        using( var backBuffer = SharpDX.Direct3D11.Texture2D.FromSwapChain<SharpDX.Direct3D11.Texture2D>( this.bs_SwapChain, 0 ) )
                        {
-                               #region " RenderTargetView の作成 "
-                               //----------------
-                               this.bs_D3DRenderTargetView = new SharpDX.Direct3D11.RenderTargetView( this.bs_D3DDevice, backBuffer );
-                               //----------------
-                               #endregion
-                               #region " 深度ステンシルテクスチャの作成 "
-                               //----------------
-                               var descDepth = backBuffer.Description;
-                               //descDepth.Width = backBuffer.Description.Width;       → backBuffer に同じ
-                               //descDepth.Height = backBuffer.Description.Height;     → 同上
-                               descDepth.MipLevels = 1;    // ミップマップレベル数
-                               descDepth.ArraySize = 1;    // 配列サイズ
-                               descDepth.Format = SharpDX.DXGI.Format.D32_Float;   // フォーマット(深度のみ)
-                               descDepth.Usage = SharpDX.Direct3D11.ResourceUsage.Default; // デフォルト使用法
-                               descDepth.BindFlags = SharpDX.Direct3D11.BindFlags.DepthStencil;    // 深度ステンシル
-                               descDepth.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None;  // CPUからはアクセスしない
-                               descDepth.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None;    // その他の設定なし
-
-                               this.bs_D3DDepthStencil = new SharpDX.Direct3D11.Texture2D( this.bs_D3DDevice, descDepth );
-                               //----------------
-                               #endregion
-                               #region " 深度ステンシルビューの作成 "
-                               //----------------
-                               var descDSV = new SharpDX.Direct3D11.DepthStencilViewDescription() {
-                                       Format = descDepth.Format,
-                                       Dimension = SharpDX.Direct3D11.DepthStencilViewDimension.Texture2D,
-                                       Flags = SharpDX.Direct3D11.DepthStencilViewFlags.None,
-                               };
-                               descDSV.Texture2D.MipSlice = 0;
-                               this.bs_D3DDepthStencilView = new SharpDX.Direct3D11.DepthStencilView(
-                                       this.bs_D3DDevice,
-                                       this.bs_D3DDepthStencil,
-                                       descDSV );
-                               //----------------
-                               #endregion
-                               #region " ビューポートの設定 "
-                               //----------------
-                               this.bs_D3DViewPort[ 0 ] = new SharpDX.Mathematics.Interop.RawViewportF() {
-                                       X = 0.0f,
-                                       Y = 0.0f,
-                                       Width = (float) backBuffer.Description.Width,
-                                       Height = (float) backBuffer.Description.Height,
-                                       MinDepth = 0.0f,
-                                       MaxDepth = 1.0f,
-                               };
-                               //----------------
-                               #endregion
-                               #region " テクスチャの共有リソースの作成 "
-                               //----------------
-                               FDK.メディア.テクスチャ.共有リソースを作成する( this );
-                               //----------------
-                               #endregion
+                               var d3dDevice = (SharpDX.Direct3D11.Device) null;
+                               using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
+                               {
+                                       #region " RenderTargetView の作成 "
+                                       //----------------
+                                       this.bs_D3DRenderTargetView = new SharpDX.Direct3D11.RenderTargetView( d3dDevice, backBuffer );
+                                       //----------------
+                                       #endregion
+                                       #region " 深度ステンシルテクスチャの作成 "
+                                       //----------------
+                                       var descDepth = backBuffer.Description;
+                                       //descDepth.Width = backBuffer.Description.Width;       → backBuffer に同じ
+                                       //descDepth.Height = backBuffer.Description.Height;     → 同上
+                                       descDepth.MipLevels = 1;    // ミップマップレベル数
+                                       descDepth.ArraySize = 1;    // 配列サイズ
+                                       descDepth.Format = SharpDX.DXGI.Format.D32_Float;   // フォーマット(深度のみ)
+                                       descDepth.Usage = SharpDX.Direct3D11.ResourceUsage.Default; // デフォルト使用法
+                                       descDepth.BindFlags = SharpDX.Direct3D11.BindFlags.DepthStencil;    // 深度ステンシル
+                                       descDepth.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None;  // CPUからはアクセスしない
+                                       descDepth.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None;    // その他の設定なし
+                                       this.bs_D3DDepthStencil = new SharpDX.Direct3D11.Texture2D( d3dDevice, descDepth );
+                                       //----------------
+                                       #endregion
+                                       #region " 深度ステンシルビューの作成 "
+                                       //----------------
+                                       var descDSV = new SharpDX.Direct3D11.DepthStencilViewDescription() {
+                                               Format = descDepth.Format,
+                                               Dimension = SharpDX.Direct3D11.DepthStencilViewDimension.Texture2D,
+                                               Flags = SharpDX.Direct3D11.DepthStencilViewFlags.None,
+                                       };
+                                       descDSV.Texture2D.MipSlice = 0;
+                                       this.bs_D3DDepthStencilView = new SharpDX.Direct3D11.DepthStencilView( d3dDevice, this.bs_D3DDepthStencil, descDSV );
+                                       //----------------
+                                       #endregion
+                                       #region " ビューポートの設定 "
+                                       //----------------
+                                       this.bs_D3DViewPort[ 0 ] = new SharpDX.Mathematics.Interop.RawViewportF() {
+                                               X = 0.0f,
+                                               Y = 0.0f,
+                                               Width = (float) backBuffer.Description.Width,
+                                               Height = (float) backBuffer.Description.Height,
+                                               MinDepth = 0.0f,
+                                               MaxDepth = 1.0f,
+                                       };
+                                       //----------------
+                                       #endregion
+                                       #region " テクスチャの共有リソースの作成 "
+                                       //----------------
+                                       FDK.メディア.テクスチャ.共有リソースを作成する( this );
+                                       //----------------
+                                       #endregion
+                               }
                        }
                }
                public void サイズに依存するリソースを解放する()
                {
-                       // 描画ターゲットを解除する。
-                       this.D3DDevice.ImmediateContext.OutputMerger.ResetTargets();
+                       var d3dDevice = (SharpDX.Direct3D11.Device) null;
+                       using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
+                       {
+                               // 描画ターゲットを解除する。
+                               d3dDevice.ImmediateContext.OutputMerger.ResetTargets();
 
-                       FDK.メディア.テクスチャ.共有リソースを解放する();
-                       this.bs_D3DDepthStencilView?.Dispose();
-                       this.bs_D3DDepthStencil?.Dispose();
-                       this.bs_D3DRenderTargetView?.Dispose();
-                       //this.bs_SwapChain?.Dispose(); → スワップチェーンは解放しない(生成・解放はデバイスとセット)。
+                               FDK.メディア.テクスチャ.共有リソースを解放する();
+                               this.bs_D3DDepthStencilView?.Dispose();
+                               this.bs_D3DDepthStencil?.Dispose();
+                               this.bs_D3DRenderTargetView?.Dispose();
+                               //this.bs_SwapChain?.Dispose(); → スワップチェーンは解放しない(生成・解放はデバイスとセット)。
 
-                       // (0,0)は、サイズ依存リソース無効の印。
-                       this.物理画面サイズpx = new SharpDX.Size2F( 0, 0 );
+                               // (0,0)は、サイズ依存リソース無効の印。
+                               this.物理画面サイズpx = new SharpDX.Size2F( 0, 0 );
+                       }
                }
                public void D3Dデバイスが消失していれば再構築する( out bool 異常状態なのでアプリを終了せよ )
                {
-                       異常状態なのでアプリを終了せよ = false;
+                       var d3dDevice = (SharpDX.Direct3D11.Device) null;
+                       using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
+                       {
+                               異常状態なのでアプリを終了せよ = false;
 
-                       var 削除理由 = this.bs_D3DDevice.DeviceRemovedReason;
-                       if( 削除理由.Success )
-                               return;
+                               var 削除理由 = d3dDevice.DeviceRemovedReason;
+                               if( 削除理由.Success )
+                                       return;
 
-                       var エラー詳細 = new[] {
+                               var エラー詳細 = new[] {
                                        new { Code = SharpDX.DXGI.ResultCode.DeviceHung.Code, Info = SharpDX.DXGI.ResultCode.DeviceHung.ApiCode, Rebuild = true },
                                        new { Code = SharpDX.DXGI.ResultCode.DeviceReset.Code, Info = SharpDX.DXGI.ResultCode.DeviceReset.ApiCode, Rebuild = true },
                                        new { Code = SharpDX.DXGI.ResultCode.DeviceRemoved.Code, Info = SharpDX.DXGI.ResultCode.DeviceRemoved.ApiCode, Rebuild = false },
@@ -250,16 +298,17 @@ namespace FDK.メディア
                                        new { Code = SharpDX.DXGI.ResultCode.InvalidCall.Code, Info = SharpDX.DXGI.ResultCode.InvalidCall.ApiCode, Rebuild = false },
                                }.First( ( エラー ) => エラー.Code == 削除理由.Code );  // 見つからないなら System.InvalidOperationException 。
 
-                       Trace.WriteLine( $"D3Dデバイスが消失しました: {エラー詳細.Info}" );
+                               Trace.WriteLine( $"D3Dデバイスが消失しました: {エラー詳細.Info}" );
 
-                       if( エラー詳細.Rebuild )
-                       {
-                               this.すべてのリソースを解放する();
-                               this.すべてのリソースを作成する();
-                       }
-                       else
-                       {
-                               異常状態なのでアプリを終了せよ = true;
+                               if( エラー詳細.Rebuild )
+                               {
+                                       this.すべてのリソースを解放する();
+                                       this.すべてのリソースを作成する();
+                               }
+                               else
+                               {
+                                       異常状態なのでアプリを終了せよ = true;
+                               }
                        }
                }
 
@@ -270,7 +319,7 @@ namespace FDK.メディア
 
                #region " バックストア。"
                //----------------
-               private SharpDX.Direct3D11.Device bs_D3DDevice = null;
+               private SharpDX.MediaFoundation.DXGIDeviceManager bs_DXGIDeviceManager = null;
                private SharpDX.DXGI.SwapChain bs_SwapChain = null;
                private SharpDX.Mathematics.Interop.RawViewportF[] bs_D3DViewPort = new SharpDX.Mathematics.Interop.RawViewportF[ 1 ];
                private SharpDX.Direct3D11.DepthStencilState bs_D3DDepthStencilState = null;
diff --git a/FDK24/同期/AutoD3DDeviceLock.cs b/FDK24/同期/AutoD3DDeviceLock.cs
new file mode 100644 (file)
index 0000000..6f6bb75
--- /dev/null
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+
+namespace FDK.同期
+{
+       /// <summary>
+       /// DXGIデバイスマネージャからD3Dデバイスを取得するためのロック機構。
+       /// </summary>
+       /// <remarks>
+       /// MediaFoundation と Direct3D は、DXGI のロックを介して Direct3Dデバイス を共有する。
+       /// </remarks>
+       public class AutoD3DDeviceLock : IDisposable
+       {
+               public AutoD3DDeviceLock( SharpDX.MediaFoundation.DXGIDeviceManager deviceManager, out SharpDX.Direct3D11.Device d3dDevice )
+               {
+                       this.deviceManager = deviceManager;
+                       this.deviceHandle = this.deviceManager.OpenDeviceHandle();
+                       this.デバイスをロックし取得する( out d3dDevice );
+               }
+               public void Dispose()
+               {
+                       this.デバイスを解放しロックを解除する();
+                       //Utility.Disposeする( ref this.deviceManager ); → ここで Dispose してはならない。Dispose する責任は呼び出しもとにある。
+                       this.deviceManager = null; // 自分の参照だけを外す。
+               }
+
+               private void デバイスをロックし取得する( out SharpDX.Direct3D11.Device d3dDevice )
+               {
+                       var dev = this.deviceManager.LockDevice(
+                               this.deviceHandle,
+                               typeof( SharpDX.Direct3D11.Device ).GUID,
+                               true );   // Lockできるまでブロックする
+
+                       d3dDevice = new SharpDX.Direct3D11.Device( dev );
+               }
+               private void デバイスを解放しロックを解除する()
+               {
+                       if( IntPtr.Zero == this.deviceHandle )
+                               return;
+
+                       this.deviceManager.UnlockDevice( this.deviceHandle );
+                       this.deviceManager.CloseDeviceHandle( this.deviceHandle );
+                       this.deviceHandle = IntPtr.Zero;
+               }
+
+               private SharpDX.MediaFoundation.DXGIDeviceManager deviceManager = null;
+               private IntPtr deviceHandle = IntPtr.Zero;
+       }
+}
index 444e68e..1465ea2 100644 (file)
@@ -45,20 +45,22 @@ namespace StrokeStyleT
                                this.testTexture.活性化する( this.デバイスリソース );
                        }
 
-                       var d3dContext = this.デバイスリソース.D3DDevice.ImmediateContext;
-
-                       #region " ビューをクリアする。"
-                       //----------------
-                       d3dContext.ClearRenderTargetView(
-                               this.デバイスリソース.D3DRenderTargetView, SharpDX.Color4.Black );
+                       var d3dDevice = (SharpDX.Direct3D11.Device) null;
+                       using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.デバイスリソース.DXGIDeviceManager, out d3dDevice ) )
+                       {
+                               #region " ビューをクリアする。"
+                               //----------------
+                               d3dDevice.ImmediateContext.ClearRenderTargetView(
+                                       this.デバイスリソース.D3DRenderTargetView, SharpDX.Color4.Black );
 
-                       d3dContext.ClearDepthStencilView(
-                               this.デバイスリソース.D3DDepthStencilView,
-                               SharpDX.Direct3D11.DepthStencilClearFlags.Depth,    // ここでは深度バッファのみ。
-                               depth: 1.0f,
-                               stencil: 0 );
-                       //----------------
-                       #endregion
+                               d3dDevice.ImmediateContext.ClearDepthStencilView(
+                                       this.デバイスリソース.D3DDepthStencilView,
+                                       SharpDX.Direct3D11.DepthStencilClearFlags.Depth,    // ここでは深度バッファのみ。
+                                       depth: 1.0f,
+                                       stencil: 0 );
+                               //----------------
+                               #endregion
+                       }
 
 #warning " テストコード。"
                        var matScale = SharpDX.Matrix.Scaling( 320f, 240f, 1.0f );