Checking architecture not working for me

Started by
6 comments, last by NikiTo 6 years, 11 months ago

(if the error is pity, please, forgive me, I am new to C++)

This code:


D3D12_FEATURE_DATA_D3D12_OPTIONS tiers;
if (FAILED(adapterList[i].Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &tiers, sizeof(tiers)))) {
    std::cout << "Failed to query the options for adapter " << i << "." << std::endl;
}
else {
    std::cout << "Options query for adapter " << i << " SUCCEEDED" << std::endl;
}

D3D12_FEATURE_DATA_ARCHITECTURE arch;
if (FAILED(adapterList[i].Device->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE, &arch, sizeof(arch))))
{
    std::cout << "Failed to query the architecture for adapter " << i << "." << std::endl;
}
else {
    std::cout << "Architecture query for adapter " << i << " SUCCEEDED" << std::endl;
}

is giving me this output:

Options query for adapter 0 SUCCEEDED
Failed to query the architecture for adapter 0.
Options query for adapter 1 SUCCEEDED
Failed to query the architecture for adapter 1.
(the shown code is inside a for-loop)

(maybe helpful details:
I read there is a D3D12_FEATURE_DATA_ARCHITECTURE1 but VS 2017 intellisense is not detecting it. I am using Intel C++ compiler through VS)

Advertisement

From what I can see, the only thing you seem to be missing is setting the Node Index on arch, think it should default to a value though it may not o.O.

try setting an arch.NodeIndex to the same value as the physical adaptor, cause thats the only thing I can see, though at work atm so not looking too hard :P

Correct, you're passing an uninitialized struct which has in/out data. If you aren't supporting multi-node, then you should at least set the node index to 0.

Thank you, people!
I am trying to make it work the way you say, but the second device fails.

I am not sure, but I think I have to pass-in 00000 for adapter 0, 010000 for adapter 1, 0010000 for adapter 2 etc.(numbers of adapters start from zero)
I will keep trying, but could you tell me how to pass it? I will code it, no problem, but you could tell me how it exactly goes this way maybe:
device 0 is 0000000

device 1 is 1000000

device 2 is 0100000

device 3 is 0010000
knowing the exact way it goes will let me to program it to be scalable. I now have 2 devices, but maybe in the future I could have 10 :)

You're (probably) not running on a multi-node system. You should always pass 0 for the node index, unless you are sure there is more than one node. Nodes are not the same as logical DXGI adapters. A single DXGI adapter may have multiple nodes - this is usually the case for SLI/CrossFire.

Before attempting to get the architecture, i detect three adapters, intel, radeon and the fake one windows provide. Then i see intel is initializing at dx12 and radeon too but slightly higher revision and tier 3 while intel has tier 1. I print their full names. I am printing all this to be sure all works because i am new to C++. I can run well various multi-adapter demos too with no problems. I am 98% sure my code detects and initializes 2 adapters. I just need to be sure how very exactly the nodeIndex is passed because i could fall into false positive with only two adapters. And if some day i have more adapters code will crash if not coded correctly, and i will probably have bad time debugging it.

Using IDXGIFactory, you can EnumAdapters to find those 3 adapters, yes. Then if you create a D3D12 device on each of them, you can discover that some of them might be made up of multiple nodes. See ID3D12Device::GetNodeCount. Each node can theoretically have a different architecture. You can target certain API objects at multiple nodes (e.g. a resource or heap can be visible to multiple nodes through its VisibleNodeMask), while other API objects must belong to a single done (e.g. a command list takes a node mask that must only have a single node bit set). However to use a resource on a device created on a different IDXGIAdapter, it must be created as SHARED_CROSS_ADAPTER. Essentially, nodes are a lightweight way of using multiple GPUs that belong to the same IHV and tend to have similar/identical properties.

Unless you're running on an SLI/CrossFire configuration, GetNodeCount() will probably return 1. For node indices, the API will only accept 0. For node masks, the API will accept 0 (i.e. default) or 1 (1 << 0, indicating node 0). If there was a second node, then GetNodeCount() would return 2, the API would accept 0 or 1 for node indices, and for node masks you could specify 0 or 1 to target just the first GPU, 2 to target the second, and 3 to target both (if applicable).

Unless you're attempting to take advantage of SLI/CrossFire, you can ignore the node indices/mask and just use 0.

Thank you very much, Jesse! I will dive again into the whole matter to gain better understanding of multi-adapters.

If I understood it correctly, on a computer there could be various adapters and each of those adapters could have various sub-adapters(said in a simply way). For now I will attend only the case of my computer. It is just too much for me now to program against all cases.

last output:
Adapter 0 has 1 nodes
Adapter 1 has 1 nodes
Architecture test for adapter 0 SUCCEEDED
Architecture of adapter 0 is UMA
Architecture test for adapter 1 SUCCEEDED
Architecture of adapter 1 is NOT UMA

This topic is closed to new replies.

Advertisement