D3D11 Debug Layer的bug

4 篇文章 0 订阅
3 篇文章 0 订阅

在开发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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值