Applications d’échantillonnage multiple dans plateforme Windows universelle (UWP) Multisampling in Universal Windows Platform (UWP) apps

Découvrez comment utiliser l’échantillonnage multiple dans des applications de plateforme Windows universelle (UWP) générées avec Direct3D.Learn how to use multisampling in Universal Windows Platform (UWP) apps built with Direct3D. L’échantillonnage multiple, également appelé anticrénelage multi-échantillon, est une technique graphique utilisée pour réduire l’apparence des bords crénelés.Multisampling, also known as multi-sample antialiasing, is a graphics technique used to reduce the appearance of aliased edges. Elle consiste à dessiner plus de pixels que leur nombre réel dans la cible de rendu final, puis à effectuer une moyenne des valeurs afin de conserver l’apparence d’un bord « partiel » dans certains pixels.It works by drawing more pixels than are actually in the final render target, then averaging values to maintain the appearance of a "partial" edge in certain pixels. Pour une description détaillée du fonctionnement réel de l’échantillonnage multiple dans Direct3D, voir Règles de rastérisation de l’anticrénelage multi-échantillon.For a detailed description of how multisampling actually works in Direct3D, see Multisample Anti-Aliasing Rasterization Rules.

Échantillonnage multiple et chaîne d’échange de modèle de retournementMultisampling and the flip model swap chain

Les applications UWP qui utilisent DirectX doivent utiliser des chaînes d’échange de modèle de retournement.UWP apps that use DirectX must use flip model swap chains. Les chaînes d’échange de modèle de retournement ne prennent pas en charge directement l’échantillonnage multiple. Toutefois, l’échantillonnage multiple peut être appliqué de manière différente en affichant la scène vers une vue de la cible de rendu échantillonnée plusieurs fois, puis en résolvant la cible de rendu échantillonnée plusieurs fois dans la mémoire tampon d’arrière-plan avant sa présentation.Flip model swap chains don't support multisampling directly, but multisampling can still be applied in a different way by rendering the scene to a multisampled render target view, and then resolving the multisampled render target to the back buffer before presenting. Cet article décrit les étapes nécessaires à l’ajout de l’échantillonnage multiple à vos applications UWP.This article explains the steps required to add multisampling to your UWP app.

Comment utiliser l’échantillonnage multipleHow to use multisampling

Les niveaux de fonctionnalités Direct3D garantissent la prise en charge des possibilités minimales et spécifiques de dénombrement d’échantillons. En outre, ils garantissent que certains formats de mémoire tampon seront disponibles pour la prise en charge de l’échantillonnage multiple.Direct3D feature levels guarantee support for specific, minimum sample count capabilities, and guarantee certain buffer formats will be available that support multisampling. Les périphériques graphiques prennent souvent en charge un éventail plus large de formats et de nombres d’échantillons que le minimum requis.Graphics devices often support a wider range of formats and sample counts than the minimum required. La prise en charge de l’échantillonnage multiple peut être déterminée au moment de l’exécution en vérifiant la prise en charge des fonctionnalités d’échantillonnage multiple avec des formats DXGI spécifiques, puis en vérifiant les nombres d’échantillons utilisables avec chaque format pris en charge.Multisampling support can be determined at run-time by checking feature support for multisampling with specific DXGI formats, and then checking the sample counts you can use with each supported format.

  1. Appelez ID3D11Device :: CheckFeatureSupport pour savoir quels formats de dxgi peuvent être utilisés avec l’échantillonnage multiple.Call ID3D11Device::CheckFeatureSupport to find out which DXGI formats can be used with multisampling. Fournissez les formats de cibles de rendu utilisables par votre jeu.Supply the render target formats your game can use. La cible de rendu et la cible de résolution doivent utiliser le même format. par conséquent, assurez-vous que le ** _ format d3d11 _ prend en charge les _ exemples _ RENDERTARGET** et le ** _ format d3d11 _ prend en charge l' _ échantillonnage _ **multi.Both the render target and resolve target must use the same format, so check for both D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET and D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE.

    **Niveau de fonctionnalité 9 :  ** Bien que les appareils de niveau 9 garantissent la prise en charge des formats de cible de rendu multiéchantillonnés, la prise en charge n’est pas garantie pour les cibles d’échantillonnage multiversion.**Feature level 9:  ** Although feature level 9 devices guarantee support for multisampled render target formats, support is not guaranteed for multisample resolve targets. Cette vérification est nécessaire avant toute tentative d’utilisation de la technique d’échantillonnage multiple décrite dans cette rubrique.So this check is necessary before trying to use the multisampling technique described in this topic.

    Le code suivant vérifie la prise en charge de l’échantillonnage multiple pour toutes les _ valeurs de format dxgi :The following code checks multisampling support for all the DXGI_FORMAT values:

    // Determine the format support for multisampling.
    for (UINT i = 1; i < DXGI_FORMAT_MAX; i++)
    {
        DXGI_FORMAT inFormat = safe_cast<DXGI_FORMAT>(i);
        UINT formatSupport = 0;
        HRESULT hr = m_d3dDevice->CheckFormatSupport(inFormat, &formatSupport);
    
        if ((formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE) &&
            (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET)
            )
        {
            m_supportInfo->SetFormatSupport(i, true);
        }
        else
        {
            m_supportInfo->SetFormatSupport(i, false);
        }
    }
    
  2. Pour chaque format pris en charge, interrogez la prise en charge du nombre d’échantillons en appelant ID3D11Device :: CheckMultisampleQualityLevels.For each supported format, query for sample count support by calling ID3D11Device::CheckMultisampleQualityLevels.

    Le code suivant vérifie la prise en charge de la taille des échantillons pour les formats DXGI pris en charge :The following code checks sample size support for supported DXGI formats:

    // Find available sample sizes for each supported format.
    for (unsigned int i = 0; i < DXGI_FORMAT_MAX; i++)
    {
        for (unsigned int j = 1; j < MAX_SAMPLES_CHECK; j++)
        {
            UINT numQualityFlags;
    
            HRESULT test = m_d3dDevice->CheckMultisampleQualityLevels(
                (DXGI_FORMAT) i,
                j,
                &numQualityFlags
                );
    
            if (SUCCEEDED(test) && (numQualityFlags > 0))
            {
                m_supportInfo->SetSampleSize(i, j, 1);
                m_supportInfo->SetQualityFlagsAt(i, j, numQualityFlags);
            }
        }
    }
    

    Remarque    Utilisez ID3D11Device2 :: CheckMultisampleQualityLevels1 à la place si vous devez vérifier la prise en charge de l’échantillonnage multiversion pour les mémoires tampons de ressources en mosaïque.Note   Use ID3D11Device2::CheckMultisampleQualityLevels1 instead if you need to check multisample support for tiled resource buffers.

     

  3. Créez un tampon et un affichage de la cible de rendu avec le nombre d’échantillons souhaité.Create a buffer and render target view with the desired sample count. Utilisez le même _ format, la même largeur et la même hauteur dxgi que la chaîne de permutation, mais spécifiez un nombre d’échantillons supérieur à 1 et utilisez une dimension de texture à échantillonnages (d3d11 de _ _ dimension RTV _ TEXTURE2DMS par exemple).Use the same DXGI_FORMAT, width, and height as the swap chain, but specify a sample count greater than 1 and use a multisampled texture dimension (D3D11_RTV_DIMENSION_TEXTURE2DMS for example). Si nécessaire, vous pouvez recréer la chaîne d’échange avec de nouveaux paramètres optimaux pour l’échantillonnage multiple.If necessary, you can re-create the swap chain with new settings that are optimal for multisampling.

    Le code suivant crée une cible de rendu échantillonnée plusieurs fois :The following code creates a multisampled render target:

    float widthMulti = m_d3dRenderTargetSize.Width;
    float heightMulti = m_d3dRenderTargetSize.Height;
    
    D3D11_TEXTURE2D_DESC offScreenSurfaceDesc;
    ZeroMemory(&offScreenSurfaceDesc, sizeof(D3D11_TEXTURE2D_DESC));
    
    offScreenSurfaceDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    offScreenSurfaceDesc.Width = static_cast<UINT>(widthMulti);
    offScreenSurfaceDesc.Height = static_cast<UINT>(heightMulti);
    offScreenSurfaceDesc.BindFlags = D3D11_BIND_RENDER_TARGET;
    offScreenSurfaceDesc.MipLevels = 1;
    offScreenSurfaceDesc.ArraySize = 1;
    offScreenSurfaceDesc.SampleDesc.Count = m_sampleSize;
    offScreenSurfaceDesc.SampleDesc.Quality = m_qualityFlags;
    
    // Create a surface that's multisampled.
    DX::ThrowIfFailed(
        m_d3dDevice->CreateTexture2D(
        &offScreenSurfaceDesc,
        nullptr,
        &m_offScreenSurface)
        );
    
    // Create a render target view. 
    CD3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc(D3D11_RTV_DIMENSION_TEXTURE2DMS);
    DX::ThrowIfFailed(
        m_d3dDevice->CreateRenderTargetView(
        m_offScreenSurface.Get(),
        &renderTargetViewDesc,
        &m_d3dRenderTargetView
        )
        );
    
  4. Le tampon de profondeur doit avoir la même largeur, la même hauteur, le même nombre d’échantillons et la même dimension de texture que la cible de rendu échantillonnée plusieurs fois.The depth buffer must have the same width, height, sample count, and texture dimension to match the multisampled render target.

    Le code suivant crée un tampon de profondeur échantillonné plusieurs fois :The following code creates a multisampled depth buffer:

    // Create a depth stencil view for use with 3D rendering if needed.
    CD3D11_TEXTURE2D_DESC depthStencilDesc(
        DXGI_FORMAT_D24_UNORM_S8_UINT,
        static_cast<UINT>(widthMulti),
        static_cast<UINT>(heightMulti),
        1, // This depth stencil view has only one texture.
        1, // Use a single mipmap level.
        D3D11_BIND_DEPTH_STENCIL,
        D3D11_USAGE_DEFAULT,
        0,
        m_sampleSize,
        m_qualityFlags
        );
    
    ComPtr<ID3D11Texture2D> depthStencil;
    DX::ThrowIfFailed(
        m_d3dDevice->CreateTexture2D(
        &depthStencilDesc,
        nullptr,
        &depthStencil
        )
        );
    
    CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2DMS);
    DX::ThrowIfFailed(
        m_d3dDevice->CreateDepthStencilView(
        depthStencil.Get(),
        &depthStencilViewDesc,
        &m_d3dDepthStencilView
        )
        );
    
  5. Il faut ensuite créer la fenêtre d’affichage, car la largeur et la hauteur de la fenêtre d’affichage doivent également correspondre à celles de la cible de rendu.Now is a good time to create the viewport, because the viewport width and height must also match the render target.

    Le code suivant crée une fenêtre d’affichage :The following code creates a viewport:

    // Set the 3D rendering viewport to target the entire window.
    m_screenViewport = CD3D11_VIEWPORT(
        0.0f,
        0.0f,
        widthMulti / m_scalingFactor,
        heightMulti / m_scalingFactor
        );
    
    m_d3dContext->RSSetViewports(1, &m_screenViewport);
    
  6. Effectuez le rendu de chaque image vers la cible de rendu échantillonnée plusieurs fois.Render each frame to the multisampled render target. Une fois le rendu terminé, appelez ID3D11DeviceContext :: ResolveSubresource avant de présenter le frame.When rendering is complete, call ID3D11DeviceContext::ResolveSubresource before presenting the frame. Cela indique à Direct3D qu’il doit effectuer l’opération d’échantillonnage multiple, calculer la valeur de chaque pixel à afficher et placer le résultat en mémoire tampon d’arrière-plan.This instructs Direct3D to peform the multisampling operation, computing the value of each pixel for display and placing the result in the back buffer. La mémoire tampon d’arrière-plan contient l’image finale sans crénelage et peut être présentée.The back buffer then contains the final anti-aliased image and can be presented.

    Le code suivant résout la sous-ressource avant de présenter l’image :The following code resolves the subresource before presenting the frame:

    if (m_sampleSize > 1)
    {
        unsigned int sub = D3D11CalcSubresource(0, 0, 1);
    
        m_d3dContext->ResolveSubresource(
            m_backBuffer.Get(),
            sub,
            m_offScreenSurface.Get(),
            sub,
            DXGI_FORMAT_B8G8R8A8_UNORM
            );
    }
    
    // The first argument instructs DXGI to block until VSync, putting the application
    // to sleep until the next VSync. This ensures that we don't waste any cycles rendering
    // frames that will never be displayed to the screen.
    hr = m_swapChain->Present(1, 0);