Esempio n. 1
0
UnorderedAccessView::UnorderedAccessView(UnderlyingResource resource, Flags::BitField field)
{
    if (!resource) {
        Throw(::Exceptions::BasicLabel("NULL resource passed to DepthStencilView constructor"));
    }

    intrusive_ptr<ID3D::UnorderedAccessView> view;
    D3DBufferDesc bufferDesc(resource);
    auto buffer = QueryInterfaceCast<ID3D::Buffer>(resource);
    if (buffer) {
        D3D11_UNORDERED_ACCESS_VIEW_DESC viewDesc;
        viewDesc.Format = DXGI_FORMAT_UNKNOWN;
        viewDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
        viewDesc.Buffer.FirstElement = 0;
        viewDesc.Buffer.NumElements = bufferDesc.ByteWidth / bufferDesc.StructureByteStride;
        viewDesc.Buffer.Flags = 0;
        if (field & Flags::AttachedCounter) {
            viewDesc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_COUNTER;
        }
        view = ObjectFactory(*resource).CreateUnorderedAccessView(resource, &viewDesc);
    } else {
        view = ObjectFactory(*resource).CreateUnorderedAccessView(resource);
    }

    _underlying = std::move(view);
}
Esempio n. 2
0
UnorderedAccessView::UnorderedAccessView(UnderlyingResource resource, NativeFormat::Enum format, unsigned mipSlice, bool appendBuffer, bool forceArray)
{
    if (!resource) {
        Throw(::Exceptions::BasicLabel("NULL resource passed to UnorderedAccessView constructor"));
    }

    intrusive_ptr<ID3D::UnorderedAccessView> view = nullptr;
    if (format == NativeFormat::Unknown && mipSlice == 0 && !appendBuffer && !forceArray) {
        view = ObjectFactory(*resource).CreateUnorderedAccessView(resource);
    } else {
        D3D11_UNORDERED_ACCESS_VIEW_DESC viewDesc;
        viewDesc.Format = AsDXGIFormat(format);

        TextureDesc2D textureDesc(resource);
        if (textureDesc.Width > 0) {
            if (textureDesc.ArraySize > 1 || forceArray) {
                viewDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
                viewDesc.Texture2DArray.MipSlice = mipSlice;
                viewDesc.Texture2DArray.FirstArraySlice = 0;
                viewDesc.Texture2DArray.ArraySize = textureDesc.ArraySize;
            } else {
                viewDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
                viewDesc.Texture2D.MipSlice = mipSlice;
            }
        } else {
            TextureDesc3D t3dDesc(resource);
            if (t3dDesc.Width > 0) {
                viewDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
                viewDesc.Texture3D.MipSlice = mipSlice;
                viewDesc.Texture3D.FirstWSlice = 0;
                viewDesc.Texture3D.WSize = (UINT)-1;
            } else {
                TextureDesc1D t1dDesc(resource);
                if (t1dDesc.Width > 0) {
                    viewDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D;
                    viewDesc.Texture1D.MipSlice = mipSlice;
                } else {
                    D3DBufferDesc bufferDesc(resource);
                    viewDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
                    viewDesc.Buffer.FirstElement = 0;
                    viewDesc.Buffer.NumElements = bufferDesc.StructureByteStride ? (bufferDesc.ByteWidth/bufferDesc.StructureByteStride) : bufferDesc.ByteWidth;
                    viewDesc.Buffer.Flags = appendBuffer ? D3D11_BUFFER_UAV_FLAG_APPEND : 0;
                }
            }
        }

        view = ObjectFactory(*resource).CreateUnorderedAccessView(resource, &viewDesc);
    }

    _underlying = std::move(view);
}
Esempio n. 3
0
bool CGUIShaderDX::CreateBuffers()
{
  ID3D11Device* pDevice = g_Windowing.Get3D11Device();

  // create vertex buffer
  CD3D11_BUFFER_DESC bufferDesc(sizeof(Vertex) * 4, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
  if (FAILED(pDevice->CreateBuffer(&bufferDesc, NULL, &m_pVertexBuffer)))
  {
    CLog::Log(LOGERROR, __FUNCTION__ " - Failed to create GUI vertex buffer.");
    return false;
  }

  // Create the constant buffer for WVP
  size_t buffSize = (sizeof(cbWorld) + 15) & ~15;
  CD3D11_BUFFER_DESC cbbd(buffSize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); // it can change very frequently
  if (FAILED(pDevice->CreateBuffer(&cbbd, NULL, &m_pWVPBuffer)))
  {
    CLog::Log(LOGERROR, __FUNCTION__ " - Failed to create the constant buffer.");
    return false;
  }
  m_bIsWVPDirty = true;

  CRect viewPort;
  g_Windowing.GetViewPort(viewPort);

  // initial data for viewport buffer
  m_cbViewPort.TopLeftX = viewPort.x1;
  m_cbViewPort.TopLeftY = viewPort.y1;
  m_cbViewPort.Width = viewPort.Width();
  m_cbViewPort.Height = viewPort.Height();

  cbbd.ByteWidth = sizeof(cbViewPort);
  D3D11_SUBRESOURCE_DATA initData = { &m_cbViewPort, 0, 0 };
  // create viewport buffer
  if (FAILED(pDevice->CreateBuffer(&cbbd, &initData, &m_pVPBuffer)))
    return false;

  return true;
}
Esempio n. 4
0
bool CGUIFontTTFDX::UpdateDynamicVertexBuffer(const SVertex* pSysMem, unsigned int vertex_count)
{
  ID3D11Device* pDevice = g_Windowing.Get3D11Device();
  ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context();

  if (!pDevice || !pContext)
    return false;

  unsigned width = sizeof(SVertex) * vertex_count;
  if (width > m_vertexWidth) // create or re-create
  {
    SAFE_RELEASE(m_vertexBuffer);

    CD3D11_BUFFER_DESC bufferDesc(width, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
    D3D11_SUBRESOURCE_DATA initData;
    ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA));
    initData.pSysMem = pSysMem;

    if (FAILED(pDevice->CreateBuffer(&bufferDesc, &initData, &m_vertexBuffer)))
    {
      CLog::Log(LOGERROR, __FUNCTION__ " - Failed to create the vertex buffer.");
      return false;
    }

    m_vertexWidth = width;
  }
  else
  {
    D3D11_MAPPED_SUBRESOURCE resource;
    if (FAILED(pContext->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource)))
    {
      CLog::Log(LOGERROR, __FUNCTION__ " - Failed to update the vertex buffer.");
      return false;
    }
    memcpy(resource.pData, pSysMem, width);
    pContext->Unmap(m_vertexBuffer, 0);
  }
  return true;
}
Esempio n. 5
0
bool
CompositorD3D11::Initialize()
{
  bool force = gfxPrefs::LayersAccelerationForceEnabled();

  ScopedGfxFeatureReporter reporter("D3D11 Layers", force);

  if (!gfxPlatform::CanUseDirect3D11()) {
    NS_WARNING("Direct3D 11-accelerated layers are not supported on this system.");
    return false;
  }

  HRESULT hr;

  mDevice = gfxWindowsPlatform::GetPlatform()->GetD3D11Device();

  if (!mDevice) {
    return false;
  }

  mDevice->GetImmediateContext(byRef(mContext));

  if (!mContext) {
    return false;
  }

  mFeatureLevel = mDevice->GetFeatureLevel();

  mHwnd = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);

  memset(&mVSConstants, 0, sizeof(VertexShaderConstants));

  int referenceCount = 0;
  UINT size = sizeof(referenceCount);
  // If this isn't there yet it'll fail, count will remain 0, which is correct.
  mDevice->GetPrivateData(sLayerManagerCount, &size, &referenceCount);
  referenceCount++;
  mDevice->SetPrivateData(sLayerManagerCount,
                          sizeof(referenceCount),
                          &referenceCount);

  size = sizeof(DeviceAttachmentsD3D11*);
  if (FAILED(mDevice->GetPrivateData(sDeviceAttachmentsD3D11,
                                     &size,
                                     &mAttachments))) {
    mAttachments = new DeviceAttachmentsD3D11;
    mDevice->SetPrivateData(sDeviceAttachmentsD3D11,
                            sizeof(mAttachments),
                            &mAttachments);

    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
      { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };

    hr = mDevice->CreateInputLayout(layout,
                                    sizeof(layout) / sizeof(D3D11_INPUT_ELEMENT_DESC),
                                    LayerQuadVS,
                                    sizeof(LayerQuadVS),
                                    byRef(mAttachments->mInputLayout));

    if (FAILED(hr)) {
      return false;
    }

    Vertex vertices[] = { {{0.0, 0.0}}, {{1.0, 0.0}}, {{0.0, 1.0}}, {{1.0, 1.0}} };
    CD3D11_BUFFER_DESC bufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER);
    D3D11_SUBRESOURCE_DATA data;
    data.pSysMem = (void*)vertices;

    hr = mDevice->CreateBuffer(&bufferDesc, &data, byRef(mAttachments->mVertexBuffer));

    if (FAILED(hr)) {
      return false;
    }

    if (!CreateShaders()) {
      return false;
    }

    CD3D11_BUFFER_DESC cBufferDesc(sizeof(VertexShaderConstants),
                                   D3D11_BIND_CONSTANT_BUFFER,
                                   D3D11_USAGE_DYNAMIC,
                                   D3D11_CPU_ACCESS_WRITE);

    hr = mDevice->CreateBuffer(&cBufferDesc, nullptr, byRef(mAttachments->mVSConstantBuffer));
    if (FAILED(hr)) {
      return false;
    }

    cBufferDesc.ByteWidth = sizeof(PixelShaderConstants);
    hr = mDevice->CreateBuffer(&cBufferDesc, nullptr, byRef(mAttachments->mPSConstantBuffer));
    if (FAILED(hr)) {
      return false;
    }

    CD3D11_RASTERIZER_DESC rastDesc(D3D11_DEFAULT);
    rastDesc.CullMode = D3D11_CULL_NONE;
    rastDesc.ScissorEnable = TRUE;

    hr = mDevice->CreateRasterizerState(&rastDesc, byRef(mAttachments->mRasterizerState));
    if (FAILED(hr)) {
      return false;
    }

    CD3D11_SAMPLER_DESC samplerDesc(D3D11_DEFAULT);
    hr = mDevice->CreateSamplerState(&samplerDesc, byRef(mAttachments->mLinearSamplerState));
    if (FAILED(hr)) {
      return false;
    }

    samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
    hr = mDevice->CreateSamplerState(&samplerDesc, byRef(mAttachments->mPointSamplerState));
    if (FAILED(hr)) {
      return false;
    }

    CD3D11_BLEND_DESC blendDesc(D3D11_DEFAULT);
    D3D11_RENDER_TARGET_BLEND_DESC rtBlendPremul = {
      TRUE,
      D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD,
      D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD,
      D3D11_COLOR_WRITE_ENABLE_ALL
    };
    blendDesc.RenderTarget[0] = rtBlendPremul;
    hr = mDevice->CreateBlendState(&blendDesc, byRef(mAttachments->mPremulBlendState));
    if (FAILED(hr)) {
      return false;
    }

    D3D11_RENDER_TARGET_BLEND_DESC rtBlendNonPremul = {
      TRUE,
      D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD,
      D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD,
      D3D11_COLOR_WRITE_ENABLE_ALL
    };
    blendDesc.RenderTarget[0] = rtBlendNonPremul;
    hr = mDevice->CreateBlendState(&blendDesc, byRef(mAttachments->mNonPremulBlendState));
    if (FAILED(hr)) {
      return false;
    }

    if (gfxPrefs::ComponentAlphaEnabled()) {
      D3D11_RENDER_TARGET_BLEND_DESC rtBlendComponent = {
        TRUE,
        D3D11_BLEND_ONE,
        D3D11_BLEND_INV_SRC1_COLOR,
        D3D11_BLEND_OP_ADD,
        D3D11_BLEND_ONE,
        D3D11_BLEND_INV_SRC_ALPHA,
        D3D11_BLEND_OP_ADD,
        D3D11_COLOR_WRITE_ENABLE_ALL
      };
      blendDesc.RenderTarget[0] = rtBlendComponent;
      hr = mDevice->CreateBlendState(&blendDesc, byRef(mAttachments->mComponentBlendState));
      if (FAILED(hr)) {
        return false;
      }
    }

    D3D11_RENDER_TARGET_BLEND_DESC rtBlendDisabled = {
      FALSE,
      D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD,
      D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD,
      D3D11_COLOR_WRITE_ENABLE_ALL
    };
    blendDesc.RenderTarget[0] = rtBlendDisabled;
    hr = mDevice->CreateBlendState(&blendDesc, byRef(mAttachments->mDisabledBlendState));
    if (FAILED(hr)) {
      return false;
    }
  }

  nsRefPtr<IDXGIDevice> dxgiDevice;
  nsRefPtr<IDXGIAdapter> dxgiAdapter;

  mDevice->QueryInterface(dxgiDevice.StartAssignment());
  dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter));

#ifdef MOZ_METRO
  if (IsRunningInWindowsMetro()) {
    nsRefPtr<IDXGIFactory2> dxgiFactory;
    dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment()));

    nsIntRect rect;
    mWidget->GetClientBounds(rect);

    DXGI_SWAP_CHAIN_DESC1 swapDesc = { 0 };
    // Automatically detect the width and the height from the winrt CoreWindow
    swapDesc.Width = rect.width;
    swapDesc.Height = rect.height;
    // This is the most common swapchain format
    swapDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    swapDesc.Stereo = false;
    // Don't use multi-sampling
    swapDesc.SampleDesc.Count = 1;
    swapDesc.SampleDesc.Quality = 0;
    swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    // Use double buffering to enable flip
    swapDesc.BufferCount = 2;
    swapDesc.Scaling = DXGI_SCALING_NONE;
    // All Metro style apps must use this SwapEffect
    swapDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
    swapDesc.Flags = 0;

    /**
     * Create a swap chain, this swap chain will contain the backbuffer for
     * the window we draw to. The front buffer is the full screen front
     * buffer.
    */
    nsRefPtr<IDXGISwapChain1> swapChain1;
    hr = dxgiFactory->CreateSwapChainForCoreWindow(
           dxgiDevice, (IUnknown *)mWidget->GetNativeData(NS_NATIVE_ICOREWINDOW),
           &swapDesc, nullptr, getter_AddRefs(swapChain1));
    if (FAILED(hr)) {
        return false;
    }
    mSwapChain = swapChain1;
  } else
#endif
  {
    nsRefPtr<IDXGIFactory> dxgiFactory;
    dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment()));

    DXGI_SWAP_CHAIN_DESC swapDesc;
    ::ZeroMemory(&swapDesc, sizeof(swapDesc));
    swapDesc.BufferDesc.Width = 0;
    swapDesc.BufferDesc.Height = 0;
    swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    swapDesc.BufferDesc.RefreshRate.Numerator = 60;
    swapDesc.BufferDesc.RefreshRate.Denominator = 1;
    swapDesc.SampleDesc.Count = 1;
    swapDesc.SampleDesc.Quality = 0;
    swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapDesc.BufferCount = 1;
    swapDesc.OutputWindow = mHwnd;
    swapDesc.Windowed = TRUE;
    swapDesc.Flags = 0;


    /**
     * Create a swap chain, this swap chain will contain the backbuffer for
     * the window we draw to. The front buffer is the full screen front
     * buffer.
     */
    hr = dxgiFactory->CreateSwapChain(dxgiDevice, &swapDesc, byRef(mSwapChain));
    if (FAILED(hr)) {
     return false;
    }

    // We need this because we don't want DXGI to respond to Alt+Enter.
    dxgiFactory->MakeWindowAssociation(swapDesc.OutputWindow,
                                       DXGI_MWA_NO_WINDOW_CHANGES);
  }

  reporter.SetSuccessful();
  return true;
}
bool SetupRendering(osvr::renderkit::GraphicsLibrary library) {
    // Make sure our pointers are filled in correctly.
    if (library.D3D11 == nullptr) {
        std::cerr << "SetupRendering: No D3D11 GraphicsLibrary, this should "
                     "not happen"
                  << std::endl;
        return false;
    }

    ID3D11Device* device = library.D3D11->device;
    ID3D11DeviceContext* context = library.D3D11->context;

    // Setup vertex shader
    auto hr = device->CreateVertexShader(g_triangle_vs, sizeof(g_triangle_vs),
                                         nullptr, vertexShader.GetAddressOf());
    if (FAILED(hr)) {
        return false;
    }

    // Setup pixel shader
    hr = device->CreatePixelShader(g_triangle_ps, sizeof(g_triangle_ps),
                                   nullptr, pixelShader.GetAddressOf());
    if (FAILED(hr)) {
        return false;
    }

    // Set the input layout
    ID3D11InputLayout* vertexLayout;
    D3D11_INPUT_ELEMENT_DESC layout[] = {
        {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,
         D3D11_INPUT_PER_VERTEX_DATA, 0},
    };
    hr = device->CreateInputLayout(layout, _countof(layout), g_triangle_vs,
                                   sizeof(g_triangle_vs), &vertexLayout);
    if (SUCCEEDED(hr)) {
        context->IASetInputLayout(vertexLayout);
        vertexLayout->Release();
        vertexLayout = nullptr;
    }

    // Create vertex buffer
    SimpleVertex vertices[3];
    vertices[0].Pos.x = 0.0f;
    vertices[0].Pos.y = 0.5f;
    vertices[0].Pos.z = 0.5f;
    vertices[1].Pos.x = 0.5f;
    vertices[1].Pos.y = -0.5f;
    vertices[1].Pos.z = 0.5f;
    vertices[2].Pos.x = -0.5f;
    vertices[2].Pos.y = -0.5f;
    vertices[2].Pos.z = 0.5f;
    CD3D11_BUFFER_DESC bufferDesc(sizeof(SimpleVertex) * _countof(vertices),
                                  D3D11_BIND_VERTEX_BUFFER);
    D3D11_SUBRESOURCE_DATA subResData = {vertices, 0, 0};
    hr = device->CreateBuffer(&bufferDesc, &subResData, &g_vertexBuffer);

    // Describe how depth and stencil tests should be performed.
    // In particular, that they should not be for this 2D example
    // where we want to render a triangle no matter what.
    D3D11_DEPTH_STENCIL_DESC depthStencilDescription = {};
    depthStencilDescription.DepthEnable = false;
    depthStencilDescription.StencilEnable = false;

    // Create depth stencil state and set it.
    hr = device->CreateDepthStencilState(&depthStencilDescription,
                                         &g_depthStencilState);
    if (FAILED(hr)) {
        std::cerr << "SetupRendering: Could not create depth/stencil state"
                  << std::endl;
        return false;
    }

    return true;
}
Esempio n. 7
0
bool
LayerManagerD3D10::Initialize()
{
  ScopedGfxFeatureReporter reporter("D3D10 Layers");

  HRESULT hr;

  /* Create an Nv3DVUtils instance */
  if (!mNv3DVUtils) {
    mNv3DVUtils = new Nv3DVUtils();
    if (!mNv3DVUtils) {
      NS_WARNING("Could not create a new instance of Nv3DVUtils.\n");
    }
  }

  /* Initialize the Nv3DVUtils object */
  if (mNv3DVUtils) {
    mNv3DVUtils->Initialize();
  }

  mDevice = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
  if (!mDevice) {
      return false;
  }

  /*
   * Do some post device creation setup
   */
  if (mNv3DVUtils) {
    IUnknown* devUnknown = NULL;
    if (mDevice) {
      mDevice->QueryInterface(IID_IUnknown, (void **)&devUnknown);
    }
    mNv3DVUtils->SetDeviceInfo(devUnknown);
  }

  int referenceCount = 0;
  UINT size = sizeof(referenceCount);
  // If this isn't there yet it'll fail, count will remain 0, which is correct.
  mDevice->GetPrivateData(sLayerManagerCount, &size, &referenceCount);
  referenceCount++;
  mDevice->SetPrivateData(sLayerManagerCount, sizeof(referenceCount), &referenceCount);

  DeviceAttachments *attachments;
  size = sizeof(DeviceAttachments*);
  if (FAILED(mDevice->GetPrivateData(sDeviceAttachments, &size, &attachments))) {
    attachments = new DeviceAttachments;
    mDevice->SetPrivateData(sDeviceAttachments, sizeof(attachments), &attachments);

    D3D10CreateEffectFromMemoryFunc createEffect = (D3D10CreateEffectFromMemoryFunc)
	GetProcAddress(LoadLibraryA("d3d10_1.dll"), "D3D10CreateEffectFromMemory");

    if (!createEffect) {
      return false;
    }

    hr = createEffect((void*)g_main,
                      sizeof(g_main),
                      D3D10_EFFECT_SINGLE_THREADED,
                      mDevice,
                      NULL,
                      getter_AddRefs(mEffect));
    
    if (FAILED(hr)) {
      return false;
    }

    attachments->mEffect = mEffect;
  
    D3D10_INPUT_ELEMENT_DESC layout[] =
    {
      { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    };
    D3D10_PASS_DESC passDesc;
    mEffect->GetTechniqueByName("RenderRGBLayerPremul")->GetPassByIndex(0)->
      GetDesc(&passDesc);

    hr = mDevice->CreateInputLayout(layout,
                                    sizeof(layout) / sizeof(D3D10_INPUT_ELEMENT_DESC),
                                    passDesc.pIAInputSignature,
                                    passDesc.IAInputSignatureSize,
                                    getter_AddRefs(mInputLayout));
    
    if (FAILED(hr)) {
      return false;
    }

    attachments->mInputLayout = mInputLayout;
  
    Vertex vertices[] = { {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0} };
    CD3D10_BUFFER_DESC bufferDesc(sizeof(vertices), D3D10_BIND_VERTEX_BUFFER);
    D3D10_SUBRESOURCE_DATA data;
    data.pSysMem = (void*)vertices;

    hr = mDevice->CreateBuffer(&bufferDesc, &data, getter_AddRefs(mVertexBuffer));

    if (FAILED(hr)) {
      return false;
    }

    attachments->mVertexBuffer = mVertexBuffer;
  } else {
    mEffect = attachments->mEffect;
    mVertexBuffer = attachments->mVertexBuffer;
    mInputLayout = attachments->mInputLayout;
  }

  if (HasShadowManager()) {
    reporter.SetSuccessful();
    return true;
  }

  nsRefPtr<IDXGIDevice> dxgiDevice;
  nsRefPtr<IDXGIAdapter> dxgiAdapter;
  nsRefPtr<IDXGIFactory> dxgiFactory;

  mDevice->QueryInterface(dxgiDevice.StartAssignment());
  dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter));

  dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment()));

  DXGI_SWAP_CHAIN_DESC swapDesc;
  ::ZeroMemory(&swapDesc, sizeof(swapDesc));

  swapDesc.BufferDesc.Width = 0;
  swapDesc.BufferDesc.Height = 0;
  swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
  swapDesc.BufferDesc.RefreshRate.Numerator = 60;
  swapDesc.BufferDesc.RefreshRate.Denominator = 1;
  swapDesc.SampleDesc.Count = 1;
  swapDesc.SampleDesc.Quality = 0;
  swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  swapDesc.BufferCount = 1;
  // We don't really need this flag, however it seems on some NVidia hardware
  // smaller area windows do not present properly without this flag. This flag
  // should have no negative consequences by itself. See bug 613790. This flag
  // is broken on optimus devices. As a temporary solution we don't set it
  // there, the only way of reliably detecting we're on optimus is looking for
  // the DLL. See Bug 623807.
  if (gfxWindowsPlatform::IsOptimus()) {
    swapDesc.Flags = 0;
  } else {
    swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;
  }
  swapDesc.OutputWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);
  swapDesc.Windowed = TRUE;

  /**
   * Create a swap chain, this swap chain will contain the backbuffer for
   * the window we draw to. The front buffer is the full screen front
   * buffer.
   */
  hr = dxgiFactory->CreateSwapChain(dxgiDevice, &swapDesc, getter_AddRefs(mSwapChain));

  if (FAILED(hr)) {
    return false;
  }

  // We need this because we don't want DXGI to respond to Alt+Enter.
  dxgiFactory->MakeWindowAssociation(swapDesc.OutputWindow, DXGI_MWA_NO_WINDOW_CHANGES);

  reporter.SetSuccessful();
  return true;
}