Presently I'm working on updating a Windows 11 DX12 desktop app to take advantage of the technologies introduced by DX12 Ultimate (i.e. mesh shaders, VRS & DXR).

All the official samples for Ultimate were successfully compiled in VS2022 and run in Debug build on a Core i9/RTX3070 laptop PC. As a first step, I wish to begin migrating as much static (i.e. unskinned) geometry over from the conventional (IA-vertex shader) rendering pipeline over to the Amplification->Mesh shader pipeline.

I'm naturally using code from the official samples to facilitate this, and in the process I've encountered a very strange issue which only triggers in my app, but not in the compiled source project.

The specific problem relates to setting up meshlet instancing culling & dynamic LOD selection. When setting descriptors into the mesh shader SRV heap, my app was failing to create a CBV:

// Mesh Info Buffers
cbvDesc.BufferLocation = m.MeshInfoResource->GetGPUVirtualAddress();
cbvDesc.SizeInBytes = MeshletUtils::GetAlignedSize<UINT>(sizeof(MeshInfo)); // 256 bytes which is correct
device->CreateConstantBufferView(&cbvDesc, OffsetHandle(i)); // generates error

A CBV into the descriptor range couldn't be generated because the resource's GPU address range was created with only 16 bytes:

D3D12 ERROR: ID3D12Device::CreateConstantBufferView: pDesc->BufferLocation + SizeInBytes - 1 (0x0000000008c1f0ff) exceeds end of the virtual address range of Resource (0x000001BD88FE1BF0:'MeshInfoResource', GPU VA Range: 0x0000000008c1f000 - 0x0000000008c1f00f). [ STATE_CREATION ERROR #649: CREATE_CONSTANT_BUFFER_VIEW_INVALID_RESOURCE]

What made this frustrating was the code is identical to the official sample, but the sample was compiling without issue. But after many hours of trying dumb things, I finally decided to examine the size of the MeshInfo structure, and therein lay the solution.

The MeshInfo struct is defined in the sample's Model class as:

struct MeshInfo
    uint32_t IndexSize;
    uint32_t MeshletCount;

    uint32_t LastMeshletVertCount;
    uint32_t LastMeshletPrimCount;

It is 16 bytes in size, and passed to the resource's description prior to its creation:

auto meshInfoDesc = CD3DX12_RESOURCE_DESC::Buffer(sizeof(MeshInfo));
ThrowIfFailed(device->CreateCommittedResource(&defaultHeap, D3D12_HEAP_FLAG_NONE, &meshInfoDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m.MeshInfoResource)));
SetDebugObjectName(m.MeshInfoResource.Get(), L"MeshInfoResource");

But clearly I needed a 256 byte range to conform with D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, so I changed meshInfoDesc to:

auto meshInfoDesc = CD3DX12_RESOURCE_DESC::Buffer(sizeof(MeshInfo) * 16u);

And the project compiles successfully.

So my question is, why isn't this GPU virtual address error also occurring in the sample???

PS: It was necessary to rename Model.h/Model.cpp to MeshletModel.h/MeshletModel.cpp for use in my project, which is based on the DirectX Tool Kit framework, where Model.h/Model.cpp files already exist for the DXTK rigid body animation effect.

New contributor
Maico De Blasio is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.


You must log in to answer this question.

Browse other questions tagged .