在开发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, , , grid );

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

g_uBoxVertexOffset = ;
g_uGridVertexOffset = g_uBoxVertexOffset + box.vertices.size(); g_uBoxIndexCount = box.indices.size();
g_uGridIndexCount = grid.indices.size(); g_uBoxIndexOffset = ;
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 = ; for ( UINT vertexIndex = ; 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 = ; 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 = ;
vertexBufferDesc.MiscFlags = ;
vertexBufferDesc.StructureByteStride = ; D3D11_SUBRESOURCE_DATA subresourceData;
subresourceData.pSysMem = &vVertices[];
subresourceData.SysMemPitch = ;
subresourceData.SysMemSlicePitch = ; 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 = ;
indexBufferDesc.MiscFlags = ;
indexBufferDesc.StructureByteStride = ; D3D11_SUBRESOURCE_DATA subresourceData;
subresourceData.pSysMem = &vIndices[];
subresourceData.SysMemPitch = ;
subresourceData.SysMemSlicePitch = ; 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( , , g_pShapeVertexBuffer.GetAddressOf(), &stride, &offset ); pD3DImmediateContext->DrawIndexed( g_uGridIndexCount, g_uGridIndexOffset, );

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

于是上网翻阅了一些资料,发现有不少朋友遇到过这个问题,同时确认这个是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, , sizeof(filter) );
filter.DenyList.NumIDs = ARRAYSIZE( arrHiddenMessageID );
filter.DenyList.pIDList = arrHiddenMessageID; pD3DInfoQueue->AddStorageFilterEntries( &filter );
SAFE_RELEASE( pD3DInfoQueue );
}
SAFE_RELEASE( pD3DDebug );
}
#endif

D3D11 Debug Layer的bug的更多相关文章

  1. VS2015+Win10 调试DirectX 报错

    安装完Win10调试程序突然在这个地方报错: #if (defined(DEBUG) || defined(_DEBUG)) deviceFlags |= D3D11_CREATE_DEVICE_DE ...

  2. Using an open debug interconnect model to simplify embedded systems design

    Using an open debug interconnect model to simplify embedded systems design Tom Cunningham, Freescale ...

  3. Node程序debug小记

    有时候,所见并不是所得,有些包,你需要去翻他的源码才知道为什么会这样. 背景 今天调试一个程序,用到了一个很久之前的NPM包,名为formstream,用来将form表单数据转换为流的形式进行接口调用 ...

  4. maven项目在eclipse中debug

    作为新手,出现bug后,debug找出bug还是很重要的,能节约大量找bug的时间 1.选中项目,右键点击-->run as -->run configurations 2.在run co ...

  5. 脑法之中的一个 --- DEBUG与搜索算法

    前年闲的蛋疼的时候,看过天津卫视的一档节目<非你莫属>,就来一堆面试者,上面几个壕.选人.记得有一期是给程序猿做的.当中有一个程序猿(好像是媛)傻不啦叽的说,哎呀,我每次DEBUG找到程序 ...

  6. 利用delve(dlv)在Visual Code中进行go程序的远程调试-debug方式

    最近碰到一个问题,如何在Windows的IDE或者文本编辑器上,远程调试Linux服务器上的golang程序. 虽然想说gdb走你,但既然go有dlv这样的类似Java的jdwp的原生方案,而且我用的 ...

  7. Linux 启动参数介绍

    Linux 启动参数介绍 取自2.6.18 kernel Documentation/i386/boot.txt 文件中介绍 vga= 这里的不是一个整数(在C语言表示法中,应是十进制,八进制或者十六 ...

  8. blade 已开源

    https://github.com/crazii 开源的主要原因是一个人写不动了, 而且已经很久没更新代码了. 希望有人能够感兴趣, 提供贡献. 距离上次更新日志已经很久了, 中间大概加了以下fea ...

  9. Kernel boot options

    There are three ways to pass options to the kernel and thus control its behavior: When building the ...

随机推荐

  1. Linux之uboot分析与移植20160601

    说一下uboot分析与移植: 1.下载.建立source insight工程.编译.烧写.如果无运行分析原因 tar xjf u-boot-2012.04.01.tar.bz2 cd u-boot-2 ...

  2. python2.7抓取豆瓣电影top250

    利用python2.7抓取豆瓣电影top250 1.任务说明 抓取top100电影名称 依次打印输出 2.网页解析 要进行网络爬虫,利用工具(如浏览器)查看网页HTML文件的相关内容是很有必要,我使用 ...

  3. Python学习教程(learning Python)--1.1Python程序设计流程

    Python程序设计与其他高级语言程序设计流程基本一致     step1 程序设计     step2 编写Python代码     setp3 Python语句语法纠错     step4 测试程 ...

  4. 用Java简单实现C#的参数为Action<T> Function<T,boolean>扩展方法

    直接上代码 Blog.Java public class Blog { public Blog(int id,String name) { Id=id; Name=name; } public int ...

  5. Nginx服务器架构简析

    一.Nginx的模块化 模块化结构的思想是一个很久的概念,但也正是成熟的思想造就了Nginx的巨大优越性. 我们知道Nginx从总体上来讲是有许多个模块构成的.习惯将Nginx分为5大模块分别为:核心 ...

  6. oracle 各种问题排查

    一.ORA-00257 ORA-00257归档日志写满,最简单方法.可以更改归档的大小. 二.job不自动运行解决方法 http://www.cnblogs.com/xbding/p/5861443. ...

  7. super的用法

    1.调用父类的构造方法子类可以调用由父类声明的构造方法.但是必须在子类的构造方法中使用super关键字来调用. 2.操作被隐藏的成员变量和被覆盖的成员方法如果想在子类中操作父类中被隐藏的成员变量和被覆 ...

  8. Uncaught TypeError: Cannot read property 'insertAdjacentHTML' of null

    在开发Ext 项目中如果遇到 Uncaught TypeError: Cannot read property 'insertAdjacentHTML' of null 这个错误,检查下renderT ...

  9. FPGA中如何实现除法?

    摘自:<xilinx FPGA 开发实用教程> 1)被除数重复的减去除数,直到检测到余数小于除数为止,优点:对于除数与被除数相差较小的情况下合适 2)通过如下图片方式实现+状态机.优点:挺 ...

  10. 【学习总结】iOS中NSNotification、delegate、KVO三者之间的区别与联系?

    在开发ios应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,controllers间怎么进行通信.在IOS应用不断的出现三种模式来实现这种通信: 1.委托delegation: 2.通 ...