title: DirectX -- Render a quad to a WicBitmapRenderTarget (SharpDX)
body: <p>I'm trying to use Direct3D11 to perform some image warping really fast as per <a href="https://stackoverflow.com/questions/11350000/mapping-corners-to-arbitrary-positions-using-direct2d/11362129">this previous question</a> but can't seem to get everything working together.</p>
  
  <p>Things are failing when I try to read the DXGI Surface into a Direct2D bitmap.</p>
  
  <pre><code>var renderSurface = renderTexture.QueryInterface&lt;SharpDX.DXGI.Surface&gt;();
  var props = new BitmapProperties
                  {
                      PixelFormat = new SharpDX.Direct2D1.PixelFormat(
                          Format.B8G8R8A8_UNorm,
                          AlphaMode.Premultiplied
                      )
                  };
  
  // This throws "No such interface supported"
  var direct2DBitmap = 
      new SharpDX.Direct2D1.Bitmap(_bitmapRenderTarget, renderSurface, props);
  </code></pre>
  
  <p>I've also tried to read the surface directly using the <code>Map</code> method, but that fails before I even attempt to do anything with the data:</p>
  
  <pre><code>var renderSurface = renderTexture.QueryInterface&lt;SharpDX.DXGI.Surface&gt;();
  // This throws "The parameter is incorrect."
  renderSurface.Map(MapFlags.Read);
  </code></pre>
  
  <p>More complete code is below. Also if there's anything in here that's extraneous to this job... I'm all ears. I'm not really a 3D person, just trying to solve a very specific problem that doesn't have an easy Direct2D solution.</p>
  
  <pre><code>public void AddImage(BitmapSource bitmapSource, SharpDX.Vector2[] abcd)
  {
      Device device;
      Texture2D renderTexture = null;
      device = new Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport);
      renderTexture = new Texture2D(device, new Texture2DDescription
      {
          Width = _size.Width,
          Height = _size.Height,
          Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm,
          MipLevels = 1,
          ArraySize = 1,
          SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
          BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
          Usage = ResourceUsage.Default,
      });
      var renderView = new RenderTargetView(device, renderTexture);
  
      //
      // Load the input bitmap as a texture
      //
      var texture = CreateTexture2DFromBitmap(device, bitmapSource);
      var textureView = new ShaderResourceView(device, texture);
      var sampler = new SamplerState(device, new SamplerStateDescription()
      {
          Filter = Filter.MinMagMipLinear,
          AddressU = TextureAddressMode.Wrap,
          AddressV = TextureAddressMode.Wrap,
          AddressW = TextureAddressMode.Wrap,
          BorderColor = Color.Black,
          ComparisonFunction = Comparison.Never,
          MaximumAnisotropy = 16,
          MipLodBias = 0,
          MinimumLod = 0,
          MaximumLod = 16,
      });
  
      //
      // Setup the scene
      // These shaders are from the MiniCubeTexture sample for SharpDX
      //
      var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniCubeTexture.fx", "VS", "vs_4_0");
      var vertexShader = new VertexShader(device, vertexShaderByteCode);
      var pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniCubeTexture.fx", "PS", "ps_4_0");
      var pixelShader = new PixelShader(device, pixelShaderByteCode);
  
      var layout = new InputLayout(device, ShaderSignature.GetInputSignature(vertexShaderByteCode), new[] {
          new InputElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32A32_Float, 0, 0),
      new InputElement("TEXCOORD", 0, SharpDX.DXGI.Format.R32G32_Float, 16, 0),
      });
  
      var vertices = SharpDX.Direct3D11.Buffer.Create(device, BindFlags.VertexBuffer, new[] {
      // 3D coordinates              UV Texture coordinates
          abcd[0].X, abcd[0].Y,  0.0f, 1.0f,     0.0f, 1.0f, // Front
          abcd[1].X, abcd[1].Y,  0.0f, 1.0f,     0.0f, 0.0f,
          abcd[2].X, abcd[2].Y,  0.0f, 1.0f,     1.0f, 0.0f,
          abcd[3].X, abcd[3].Y,  0.0f, 1.0f,     0.0f, 1.0f,
      });
  
      var contantBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf&lt;Matrix&gt;(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
  
      var context = device.ImmediateContext;
      context.InputAssembler.InputLayout = layout;
      context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
      context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Utilities.SizeOf&lt;Vector4&gt;() + Utilities.SizeOf&lt;Vector2&gt;(), 0));
      context.VertexShader.SetConstantBuffer(0, contantBuffer);
      context.VertexShader.Set(vertexShader);
      context.Rasterizer.SetViewports(new Viewport(0, 0, _size.Width, _size.Height, 0.0f, 1.0f));
      context.PixelShader.Set(pixelShader);
      context.PixelShader.SetSampler(0, sampler);
      context.PixelShader.SetShaderResource(0, textureView);
      context.OutputMerger.SetTargets(renderView);
  
      //
      // Render 3D
      //          
      context.ClearRenderTargetView(renderView, Colors.Transparent);
      var worldViewProj = Matrix.Identity;// Matrix.Translation (_size.Width, _size.Height / 2, 0) * Matrix.Scaling (_size.Width / 2, _size.Height / 2, 1);
      context.UpdateSubresource(ref worldViewProj, contantBuffer);
      context.Draw(4, 0);
  
      //
      // Composite
      //
  
      //Create a render target
  
      var renderSurface = renderTexture.QueryInterface&lt;SharpDX.DXGI.Surface&gt;();
      var props = new BitmapProperties
                      {
                          PixelFormat = new SharpDX.Direct2D1.PixelFormat(Format.B8G8R8A8_UNorm,AlphaMode.Premultiplied)
                      };
  
      var direct2DBitmap = new SharpDX.Direct2D1.Bitmap(_bitmapRenderTarget, renderSurface, props);
  
      _wicRenderTarget.BeginDraw();
      _wicRenderTarget.DrawBitmap(direct2DBitmap, 1.0f, SharpDX.Direct2D1.BitmapInterpolationMode.Linear);
      _wicRenderTarget.EndDraw();
  
      direct2DBitmap.Dispose();
  }
  
  private static SharpDX.Direct3D11.Texture2D CreateTexture2DFromBitmap(SharpDX.Direct3D11.Device device, SharpDX.WIC.BitmapSource bitmapSource)
  {
      // Allocate DataStream to receive the WIC image pixels
      int stride = bitmapSource.Size.Width * 4;
      using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true))
      {
          // Copy the content of the WIC to the buffer
          bitmapSource.CopyPixels(stride, buffer);
          return new SharpDX.Direct3D11.Texture2D(device, new SharpDX.Direct3D11.Texture2DDescription()
          {
              Width = bitmapSource.Size.Width,
              Height = bitmapSource.Size.Height,
              ArraySize = 1,
              BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource,
              Usage = SharpDX.Direct3D11.ResourceUsage.Immutable,
              CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None,
              Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
              MipLevels = 1,
              OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
              SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
          }, new SharpDX.DataRectangle(buffer.DataPointer, stride));
      }
  }
  </code></pre>