title: DirectX/DirectCompute CreateBuffer failure with error 0x80070057 (E_INVALIDARG)
body: <p>I'm trying to create a buffer in GPU memory to upload data from CPU. GPU access will be readonly. Data will be used as an input buffer for a compute shader. </p>
  
  <p>CreateBuffer() fails with error 0x80070057 (E_INVALIDARG). I read the docs and read it again without discovering which argument cause the failure.</p>
  
  <p>InitDevice() return success.</p>
  
  <p>Here is an extract from my code:</p>
  
  <pre><code>function TGpuImageControl.InitDevice: HRESULT;
  var
      hr                : HRESULT;
      createDeviceFlags : UINT;
      driverTypes       : array [0..0] of D3D_DRIVER_TYPE;
      numDriverTypes    : UINT;
      driverTypeIndex   : UINT;
      sd                : DXGI_SWAP_CHAIN_DESC;
      FeatureLevels     : D3D_FEATURE_LEVEL;
      featureLevel      : D3D_FEATURE_LEVEL;
  const
      D3D10_SHADER_DEBUG = 1;
  begin
      hr     := S_OK;
  
      createDeviceFlags := 0;
  {$ifdef DEBUG}
      createDeviceFlags := createDeviceFlags or D3D11_CREATE_DEVICE_DEBUG;
  {$endif}
  
  {$ifdef WARP}
      driverTypes[0] := D3D_DRIVER_TYPE_REFERENCE;
  {$else}
      driverTypes[0] := D3D_DRIVER_TYPE_HARDWARE;
  {$endif}
      numDriverTypes := SizeOf(driverTypes) div SizeOf(driverTypes[0]);
  
      ZeroMemory(@sd, SizeOf(sd));
      sd.BufferCount                        := 1;
      sd.BufferDesc.Width                   := width;
      sd.BufferDesc.Height                  := height;
      sd.BufferDesc.Format                  := DXGI_FORMAT_R8G8B8A8_UNORM;
      sd.BufferDesc.RefreshRate.Numerator   := 60;
      sd.BufferDesc.RefreshRate.Denominator := 1;
      sd.BufferUsage                        := DXGI_USAGE_RENDER_TARGET_OUTPUT or
                                               DXGI_USAGE_UNORDERED_ACCESS;//     or
                                               //DXGI_USAGE_SHADER_INPUT;
      sd.OutputWindow                       := Handle;
      sd.SampleDesc.Count                   := 1;
      sd.SampleDesc.Quality                 := 0;
      sd.Windowed                           := TRUE;
      //sd.Flags                            := DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
  
      FeatureLevels :=   D3D_FEATURE_LEVEL_11_0;
  
      for driverTypeIndex := 0 to numDriverTypes do begin
          g_driverType := driverTypes[driverTypeIndex];
          hr := D3D11CreateDeviceAndSwapChain(
                    nil,                    // Graphic Adapter, use default
                    g_driverType,           // Driver type to use
                    0,                      // HModule for software driver
                    createDeviceFlags,      // Create flags
                    @FeatureLevels,         // Feature levels
                    1,                      // Feature level size
                    D3D11_SDK_VERSION,      // SDK Version
                    @sd,                    // Swap Chain descriptor
                    g_pSwapChain,           // Out: Created swap chain
                    g_pd3dDevice,           // Out: Created device
                    featureLevel,           // Out: Feature level
                    g_pImmediateContext);   // Out: Context
          if SUCCEEDED(hr) then
              break;
      end;
      if FAILED(hr) then begin
          Result := hr;
          Exit;
      end;
  
      ImageResize();
  
      Result := S_OK;
  end;
  
  procedure TGpuImageControl.ImageResize;
  var
      hr       : HRESULT;
      sd       : DXGI_SWAP_CHAIN_DESC;
      pTexture : ID3D11Texture2D;
      vp       : D3D11_VIEWPORT;
  begin
      if g_pd3dDevice = nil then
          Exit;
  
      // release first else resize problem
      SAFE_RELEASE(IUnknown(g_pComputeOutput));
  
      g_pSwapChain.GetDesc(sd);
      hr := g_pSwapChain.ResizeBuffers(sd.BufferCount,
                                       Width,
                                       Height,
                                       sd.BufferDesc.Format,
                                       0);                   // Swap chain flags
      if FAILED(hr) then begin
          ShowError('SwapChain.ResizeBuffers failed with error %d', [hr]);
          Exit;
      end;
  
      hr := g_pSwapChain.GetBuffer(0, TGUID(ID3D11Texture2D), pTexture);
      if FAILED(hr) then begin
          ShowError('SwapChain.GetBuffer failed with error %d', [hr]);
          Exit;
      end;
  
      // create shader unordered access view on back buffer for compute shader to write into texture
      hr := g_pd3dDevice.CreateUnorderedAccessView(pTexture,
                                                   nil,
                                                   g_pComputeOutput);
      if FAILED(hr) then begin
          ShowError('pd3dDevice.CreateUnorderedAccessView failed with error %d', [hr]);
          Exit;
      end;
  
      pTexture := nil;
  
      // Setup the viewport
      vp.Width    := Width;
      vp.Height   := Height;
      vp.MinDepth := 0.0;
      vp.MaxDepth := 1.0;
      vp.TopLeftX := 0;
      vp.TopLeftY := 0;
      g_pImmediateContext.RSSetViewports(1, @vp);
  end;
  </code></pre>
  
  <p>The code which fails is the following:</p>
  
  <pre><code>function TGpuImageControl.CreateStructuredBuffer(
      uElementSize : UINT;
      uCount       : UINT;
      pInitData    : Pointer;
      out ppBufOut : ID3D11Buffer): HRESULT;
  var
      desc     : D3D11_BUFFER_DESC;
      InitData : D3D11_SUBRESOURCE_DATA;
  begin
      ppBufOut := nil;
  
      ZeroMemory(@desc, SizeOf(desc));
      desc.BindFlags           := D3D11_BIND_UNORDERED_ACCESS or
                                  D3D11_BIND_SHADER_RESOURCE;
      desc.Usage               := D3D11_USAGE_DYNAMIC;
      desc.CPUAccessFlags      := D3D11_CPU_ACCESS_WRITE;
      desc.ByteWidth           := uElementSize * uCount;
      desc.MiscFlags           := UINT(D3D11_RESOURCE_MISC_BUFFER_STRUCTURED);
      desc.StructureByteStride := uElementSize;
  
      if pInitData &lt;&gt; nil then begin
          InitData.pSysMem := pInitData;
          Result := g_pd3dDevice.CreateBuffer(desc, @InitData, ppBufOut);
      end
      else
          Result := g_pd3dDevice.CreateBuffer(desc, nil, ppBufOut);
  end;
  </code></pre>
  
  <p>When calling the function, I pass uElementSize=2, uCount=100 and pInitData pointing to an allocated 200 bytes buffer in CPU memory.</p>
  
  <p>I don't understand what I'm doing wrong.
  Any help appreciated.</p>