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, , , 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的更多相关文章
- VS2015+Win10 调试DirectX 报错
安装完Win10调试程序突然在这个地方报错: #if (defined(DEBUG) || defined(_DEBUG)) deviceFlags |= D3D11_CREATE_DEVICE_DE ...
- 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 ...
- Node程序debug小记
有时候,所见并不是所得,有些包,你需要去翻他的源码才知道为什么会这样. 背景 今天调试一个程序,用到了一个很久之前的NPM包,名为formstream,用来将form表单数据转换为流的形式进行接口调用 ...
- maven项目在eclipse中debug
作为新手,出现bug后,debug找出bug还是很重要的,能节约大量找bug的时间 1.选中项目,右键点击-->run as -->run configurations 2.在run co ...
- 脑法之中的一个 --- DEBUG与搜索算法
前年闲的蛋疼的时候,看过天津卫视的一档节目<非你莫属>,就来一堆面试者,上面几个壕.选人.记得有一期是给程序猿做的.当中有一个程序猿(好像是媛)傻不啦叽的说,哎呀,我每次DEBUG找到程序 ...
- 利用delve(dlv)在Visual Code中进行go程序的远程调试-debug方式
最近碰到一个问题,如何在Windows的IDE或者文本编辑器上,远程调试Linux服务器上的golang程序. 虽然想说gdb走你,但既然go有dlv这样的类似Java的jdwp的原生方案,而且我用的 ...
- Linux 启动参数介绍
Linux 启动参数介绍 取自2.6.18 kernel Documentation/i386/boot.txt 文件中介绍 vga= 这里的不是一个整数(在C语言表示法中,应是十进制,八进制或者十六 ...
- blade 已开源
https://github.com/crazii 开源的主要原因是一个人写不动了, 而且已经很久没更新代码了. 希望有人能够感兴趣, 提供贡献. 距离上次更新日志已经很久了, 中间大概加了以下fea ...
- Kernel boot options
There are three ways to pass options to the kernel and thus control its behavior: When building the ...
随机推荐
- Java 第三天 Gradle和其它
Gradle 是以 Groovy 语言为基础,面向Java应用为主.基于DSL(领域特定语言)语法的自动化构建工具. 下载地址 http://www.gradle.org/downloads 环境变量 ...
- Redbean:入门(三) - Exec 以及 Query 以及 ConvertToBeans
<?php //引入rb入口文件 include_once 'rb.php'; //定义dsn以及相关的数据 $dsn = 'mysql:host=localhost;dbname=hwibs_ ...
- React Native分析(index.ios.js)
定义创建组件MyComponent(index.ios.js): 'use strict' var React = require('react-native'); var { AppRegistry ...
- hdu 3288 Resource Allocation
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3288 Resource Allocation Description HDU-Sailormoon i ...
- 九度oj 1184 二叉树遍历
原题链接:http://ac.jobdu.com/problem.php?pid=1184 简单的二叉树重建,遍历. 如下: #include<cstdio> #include<cs ...
- android开发系列之git常用命令
最近因为跳槽到新公司,然后新公司里面的代码管理工具是gitLab,所以我想在这篇博客里面整理一下git常用的语法. GitLab是利用 Ruby on Rails 一个开源的版本管理系统,实现一个自托 ...
- iOS学习之C语言数组
一.一维数组 数组:具有相同类型的成员组成的一组数据 1.定义 元素:数组中存放的数据成为数组的元素 数组是构造类型 用{}来给构造类型赋初始值 类型修 ...
- Apple Watch应用开发经验谈:我遇到的那些坑
本文作者张忠良是滴答清单Apple Watch版应用的开发工程师,他用了一周的时间使用纯Objective-C语言完成了Apple Watch版滴答清单应用的开发工作.在这里,他从开发角度阐述了个人对 ...
- [转]JSON与XML的区别比较
1.定义介绍 (1).XML定义扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许 ...
- IT人为什么难以拿到高薪?
最近在论坛里看到很多人发牢骚,说薪水少,可在我看来,你们这样的人拿得到高薪才怪! 我先问一句:这里有多少人是本科的?有多少人是正规本科的(不算自考,成考和专升本)?有多少人是有学位的?有多少有学位的是 ...