Advertisement

Graphics Debugger & Invalid CPU descriptor handle

Started by October 09, 2018 01:34 PM
10 comments, last by GMCommand 6 years, 3 months ago

Hi everybody !

I have a problem with the VS Graphics Debugger and a D3D12 desktop application. When I create my depth stencil resource, I create two descriptor heaps, one with HEAP_TYPE_DSV, and one with HEAP_TYPE_CBV_SRV_UAV (to rebuild position from depth map), both calls to CreateDescriptorHeap succeed. Then I create a shader-resource view, and a depth-stencil view.

Things go well with and without the debugger, but when I use the graphics debugger, the application crashes stating that the CPU descriptor handles does not refer to a location in a descriptor heap when I call either CreateDepthStencilView or CreateShaderResourceView.

Here is my code :


{
	D3D12_DESCRIPTOR_HEAP_DESC heap_desc = {};
	heap_desc.NumDescriptors = 1;
	heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
	heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;

  	ThrowIfFailed(device->CreateDescriptorHeap(&heap_desc,
		IID_PPV_ARGS(&m_SRVDescriptorHeap)));
			   
	heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
	ThrowIfFailed(device->CreateDescriptorHeap(&heap_desc,
		IID_PPV_ARGS(&m_DSVDescriptorHeap)));
}
	
DXGI_FORMAT depth_format = DXGI_FORMAT_D24_UNORM_S8_UINT;
DXGI_FORMAT depth_format_SRV = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
	
D3D12_CLEAR_VALUE depth_clear = {};
depth_clear.Format = depth_format;
depth_clear.DepthStencil.Depth = 1.0f;
depth_clear.DepthStencil.Stencil = 0;

ThrowIfFailed(device->CreateCommittedResource(
	&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
	D3D12_HEAP_FLAG_NONE,
	&CD3DX12_RESOURCE_DESC::Tex2D(
		depth_format,
		width, height, 1, 0, 1, 0,
		D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL),
	D3D12_RESOURCE_STATE_DEPTH_WRITE,
	&depth_clear,
	IID_PPV_ARGS(&m_Resource)
));

{
	D3D12_DEPTH_STENCIL_VIEW_DESC dstencil_desc = {};
	dstencil_desc.Format = depth_format;
	dstencil_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
	dstencil_desc.Flags = D3D12_DSV_FLAG_NONE;

  	// this call causes a crash
	device->CreateDepthStencilView(m_Resource, &dstencil_desc,
		m_DSVDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
}
{
	D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = {};
	srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
	srv_desc.Format = depth_format_SRV;
	srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
	srv_desc.Texture2D.MipLevels = 1;
	
  	// this call causes a crash
	device->CreateShaderResourceView(m_Resource, &srv_desc,
		m_SRVDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
}

This is the message I get from the DebugLayer :

D3D12 ERROR: ID3D12Device::CreateShaderResourceView: Specified CPU descriptor handle ptr=0x0000000000008781 does not refer to a location in a descriptor heap.  [ EXECUTION ERROR #646: INVALID_DESCRIPTOR_HANDLE]

I have no more information with the GPUBasedValidation.

The only thing different I noticed with the graphics debugger is that the handle has a much smaller ptr (and always the same) than without it, but I suppose it's only due to the fact that the application is run in some kind of environment with the graphics debugger, right ?

PIX gives me the same error (E_PIX_INVALID_DESCRIPTOR_HANDLE).

Can anyone help me understand or give me a clue why I have this problem, please :| ?

Many Thanks :)

Have you tried this code on more than one IHV's GPU and do you have the driver fully up to date?

What about WARP / Microsoft Basic Render Device?

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

Advertisement
Quote

Have you tried this code on more than one IHV's GPU and do you have the driver fully up to date?

I only have one D3D12 compatible GPU (GTX 770), but my drivers are up to date, I updated them few days ago after updating to Windows 10 - 1809. Also tried it on an old laptop with a GeForce G102M but it crashed all the same with the graphics debugger.

Quote

What about WARP / Microsoft Basic Render Device?

When I run the application with the graphics debugger, I have 2 adapters : "Capture Adapter", and "Microsoft Basic Render Driver", but both produce the same crash :S

2 minutes ago, GMCommand said:

I only have one D3D12 compatible GPU (GTX 770), but my drivers are up to date, I updated them few days ago after updating to Windows 10 - 1809. Also tried it on an old laptop with a GeForce G102M but it crashed all the same with the graphics debugger.

When I run the application with the graphics debugger, I have 2 adapters : "Capture Adapter", and "Microsoft Basic Render Driver", but both produce the same crash :S

Are you able to provide a repro of some description?

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

40 minutes ago, ajmiles said:

Are you able to provide a repro of some description?

I tried to make a small code sample to reproduce the behaviour, but it worked fine, so I'm probably doing something wrong the the descriptor heaps... So I tried to narrow down the problem, it seems it happens after the creation of my ring buffer.

The ring buffer has 4 heaps, and the next descriptor heap I create after the ring buffer's initialization has an invalid CPU handle, be it for depth or something else.


void RingBuffer::Initialize()
{
	UINT heap_sizes[] = { 250, 0, 20, 0 };
	for (int i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++i)
	{
		m_HeapList[i].Init(m_pDevice, heap_sizes[i], D3D12_DESCRIPTOR_HEAP_TYPE(i));
	}
}

void Heap::Init(ID3D12Device* device, UINT num_descriptors, D3D12_DESCRIPTOR_HEAP_TYPE type)
{
	D3D12_DESCRIPTOR_HEAP_DESC heap_desc = {};
	heap_desc.NumDescriptors = num_descriptors;
	heap_desc.Type = type;
	if (type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
		heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
	else
		heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;

	ThrowIfFailed(device->CreateDescriptorHeap(&heap_desc, IID_PPV_ARGS(&DescriptorHeap)));

	Markers = new std::queue<SectorMarker>();

	Markers->push({
		D3D12Descriptor(DescriptorHeap->GetCPUDescriptorHandleForHeapStart(),
		DescriptorHeap->GetGPUDescriptorHandleForHeapStart()),
		0,
		0 }
	);

	AvailableMemory = Size = num_descriptors;

	DescriptorIncrementSize = device->GetDescriptorHandleIncrementSize(type);
}

The crash happens when I create descriptor heaps after calling RingBuffer::Initialize();

By the way I take this opportunity to ask another unrelated question : I know it looks stupid to dynamically allocate the std::queues here, but when I statically allocate them, the program crashes when I use the queues giving me this error :

image.png.cc37f7f9f896c1249c069597a13a6dc0.png

The std::queue are members of struct Heap, Heaps are stored as a union in the ring buffer class, which is dynamically allocated.


struct SectorMarker
{
	D3D12Descriptor Descriptor;
	UINT64 FenceValue;
	UINT Tail;
};

struct Heap
{
  ...
    std::queue<SectorMarker>* Markers;
}
class RingBuffer
{
  ...
private:
	union
	{
		struct {
			Heap m_SRVHeap;
			Heap m_SamplerHeap;
			Heap m_RTVHeap; 
			Heap m_DSVHeap;
		};
		Heap m_HeapList[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
	};
}

Any idea why ?

I'm obviously not familiar with all your code, but this looks a bit odd, no?


UINT heap_sizes[] = { 250, 0, 20, 0 };

Each of those heap sizes seems to correspond to a descriptor type, and you're asking for zero Sampler descriptors and zero DSV descriptors in the heap?

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

Advertisement
10 hours ago, ajmiles said:

I'm obviously not familiar with all your code, but this looks a bit odd, no?



UINT heap_sizes[] = { 250, 0, 20, 0 };

Each of those heap sizes seems to correspond to a descriptor type, and you're asking for zero Sampler descriptors and zero DSV descriptors in the heap?

?

Okay if I don't create zero-sized heaps, it solves the problem. I've just "finished" my ring buffer, as I didn't use the Sampler and DSV heap to copy descriptors yet, it didn't even cross my mind this could be the problem... I would have expected CreateDescriptorHeap to return an invalid parameter error code or the debug layer to tell me it was illegal though.

Can you tell me why it crashes only with the graphics debugger ?

And any idea about the std::queues ? Or should I make another topic for it ? (to be more precise, it works fine when I push elements, but crashes when I use front()/back(), and I double checked it wasn't empty) I'll try to see if I can reproduce it.

Anyway, thank you very much for you help ajmiles, it's the second time you help me :)

I know this doesn't exactly help with your problem, but have you tried using PIX or RenderDoc instead of the VS graphics debugger? I find both of those tools to be *much* more usable than the built-in VS debugger.

13 hours ago, MJP said:

I know this doesn't exactly help with your problem, but have you tried using PIX or RenderDoc instead of the VS graphics debugger? I find both of those tools to be *much* more usable than the built-in VS debugger.

I didn't know PIX until recently, but I tried it to solve my problem and it seems to have some nice features, I'll probably switch to it now :) I'll also have a look at RenderDoc, thanks :)

As for my std::queue problem, it was only a problem with the union and constructors... sorry :$

On 10/10/2018 at 8:36 AM, GMCommand said:

?

Okay if I don't create zero-sized heaps, it solves the problem. I've just "finished" my ring buffer, as I didn't use the Sampler and DSV heap to copy descriptors yet, it didn't even cross my mind this could be the problem... I would have expected CreateDescriptorHeap to return an invalid parameter error code or the debug layer to tell me it was illegal though.

Can you tell me why it crashes only with the graphics debugger ?

And any idea about the std::queues ? Or should I make another topic for it ? (to be more precise, it works fine when I push elements, but crashes when I use front()/back(), and I double checked it wasn't empty) I'll try to see if I can reproduce it.

Anyway, thank you very much for you help ajmiles, it's the second time you help me :)

Perhaps there's some quirk around zero descriptor heaps that we haven't tested. I'll try and find some time next week to see if I can reproduce any problems.

Can you confirm what version of Windows you're using right now? Run 'winver' and type out the full build number.

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

This topic is closed to new replies.

Advertisement