zoukankan      html  css  js  c++  java
  • D3D11 Debug Layer的bug

    在开发D3D应用程序时,我们会使用Debug Layer来调试应用程序,以确保我们的程序在最终发布时没有warnings和errors。不过最近在开发应用程序时遇到了这样的问题,就是我把多个网格模型的顶点数据放在一个vertex buffer中,与此同时也把它们的索引数据放在一个index buffer中,然后在绘制不同的网格模型时就需要设置相应的偏移量,代码看上去是这样的:

    首先我创建了一个box和一个grid:

    CGeometryGenerator::CreateBox( 1.0f, 1.0f, 1.0f, box );
    CGeometryGenerator::CreateGrid( 20.0f, 30.0f, 50, 40, grid );

    接着我记录下每个网格模型的顶点偏移量和索引偏移量:

    g_uBoxVertexOffset = 0;
    g_uGridVertexOffset = g_uBoxVertexOffset + box.vertices.size();
    
    g_uBoxIndexCount = box.indices.size();
    g_uGridIndexCount = grid.indices.size();
    
    g_uBoxIndexOffset = 0;
    g_uGridIndexOffset = g_uBoxIndexOffset + g_uBoxIndexCount;

    最后我将box和grid的顶点数据与索引数据存放在一个vertex buffer和index buffer中:

    // Copy vertices
    UINT uVertexCount = box.vertices.size() + grid.vertices.size() + sphere.vertices.size() + cylinder.vertices.size();
    std::vector<VertexPositionNormal> vVertices( uVertexCount );
    UINT uVertexIndex = 0;
    
    for ( UINT vertexIndex = 0; vertexIndex < box.vertices.size(); ++vertexIndex, ++uVertexIndex )
    {
        VertexPositionNormal &vertex = vVertices[uVertexIndex];
        VertexPositionNormalTangentColorTexture &boxVertex = box.vertices[vertexIndex];
            
        vertex.position = boxVertex.position;
        vertex.normal = boxVertex.normal;
    }
    
    for ( UINT vertexIndex = 0; vertexIndex < grid.vertices.size(); ++vertexIndex, ++uVertexIndex )
    {
        VertexPositionNormal &vertex = vVertices[uVertexIndex];
        VertexPositionNormalTangentColorTexture &gridVertex = grid.vertices[vertexIndex];
            
        vertex.position = gridVertex.position;
        vertex.normal = gridVertex.normal;
    }
    
    // Create vertex buffer
    {
        D3D11_BUFFER_DESC vertexBufferDesc;
        vertexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
        vertexBufferDesc.ByteWidth = sizeof(VertexPositionNormal) * uVertexCount;
        vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
        vertexBufferDesc.CPUAccessFlags = 0;
        vertexBufferDesc.MiscFlags = 0;
        vertexBufferDesc.StructureByteStride = 0;
    
        D3D11_SUBRESOURCE_DATA subresourceData;
        subresourceData.pSysMem = &vVertices[0];
        subresourceData.SysMemPitch = 0;
        subresourceData.SysMemSlicePitch = 0;
    
        HRESULT hr;
        V( pD3DDevice->CreateBuffer(&vertexBufferDesc, &subresourceData, g_pShapeVertexBuffer.ReleaseAndGetAddressOf()) );
    }
    
    // Create indices
    UINT uIndexCount = g_uBoxIndexCount + g_uGridIndexCount;
    
    std::vector<UINT> vIndices;
    vIndices.insert( vIndices.end(), box.indices.begin(), box.indices.end() );
    vIndices.insert( vIndices.end(), grid.indices.begin(), grid.indices.end() );
    
    // Create index buffer
    {
        D3D11_BUFFER_DESC indexBufferDesc;
        indexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
        indexBufferDesc.ByteWidth = sizeof(UINT) * uIndexCount;
        indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
        indexBufferDesc.CPUAccessFlags = 0;
        indexBufferDesc.MiscFlags = 0;
        indexBufferDesc.StructureByteStride = 0;
    
        D3D11_SUBRESOURCE_DATA subresourceData;
        subresourceData.pSysMem = &vIndices[0];
        subresourceData.SysMemPitch = 0;
        subresourceData.SysMemSlicePitch = 0;
    
        HRESULT hr;
        V( pD3DDevice->CreateBuffer(&indexBufferDesc, &subresourceData, g_pShapeIndexBuffer.ReleaseAndGetAddressOf()) );
    }

    因此,在绘制grid时,我就需要设置相应的偏移量来保证读取的顶点和索引数据是正确的,代码如下:

    pD3DImmediateContext->DrawIndexed( g_uGridIndexCount, g_uGridIndexOffset, g_uGridVertexOffset );

    这个时候,D3D Debug Layer就会出现错误:

    起初以为是偏移量设置出错,但是仔细检查了代码,发现没有任何问题,同时渲染结果也是正确的。于是,尝试采用另一种方式,就是在设置vertex buffer时设置偏移量:

    UINT stride = sizeof( VertexPositionNormal );
    UINT offset = g_uGridVertexOffset * sizeof(VertexPositionNormal);
    pD3DImmediateContext->IASetVertexBuffers( 0, 1, g_pShapeVertexBuffer.GetAddressOf(), &stride, &offset );
    
    pD3DImmediateContext->DrawIndexed( g_uGridIndexCount, g_uGridIndexOffset, 0 );

    此时错误就消失了,渲染也是正确的,也就是说,代码中的偏移量计算是正确的。

    于是上网翻阅了一些资料,发现有不少朋友遇到过这个问题,同时确认这个是D3D Debug Layer的bug,也就是当DrawIndexed函数中的StartIndexLocation和BaseVertexLocation参数同时不为0时,就会出现上图的warning。
    既然程序是正确的,那么有什么办法可以不让它打印这个warning呢?一个方法就是上面我提到的,在设置vertex buffer时设置偏移量。还有个办法就是通知Debug Layer隐藏这个消息:

    // Hide warning: DEVICE_DRAW_INDEX_BUFFER_TOO_SMALL which is a bug of D3D11 Debug Layer
    #if defined(DEBUG) | defined(_DEBUG)
    ID3D11Debug *pD3DDebug = NULL;
    if( SUCCEEDED(pD3DDevice->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<VOID**>(&pD3DDebug))) )
    {
        ID3D11InfoQueue *pD3DInfoQueue = NULL;
        if( SUCCEEDED(pD3DDebug->QueryInterface(__uuidof(ID3D11InfoQueue), reinterpret_cast<VOID**>(&pD3DInfoQueue))) )
        {
            D3D11_MESSAGE_ID arrHiddenMessageID[] =
            {
                D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_TOO_SMALL,
            };
                
            D3D11_INFO_QUEUE_FILTER filter;
            memset( &filter, 0, sizeof(filter) );
            filter.DenyList.NumIDs = ARRAYSIZE( arrHiddenMessageID );
            filter.DenyList.pIDList = arrHiddenMessageID;
            
            pD3DInfoQueue->AddStorageFilterEntries( &filter );
            SAFE_RELEASE( pD3DInfoQueue );
        }
        SAFE_RELEASE( pD3DDebug );
    }
    #endif
  • 相关阅读:
    UVALive 7509 Dome and Steles
    HDU 5884 Sort
    Gym 101194H Great Cells
    HDU 5451 Best Solver
    HDU 5883 The Best Path
    HDU 5875 Function
    卡特兰数
    UVa 11729 Commando War 突击战
    UVa 11292 The Dragon of Loowater 勇者斗恶龙
    Spark Scala Flink版本对应关系
  • 原文地址:https://www.cnblogs.com/twjcnblog/p/3760033.html
Copyright © 2011-2022 走看看